I'M getting an error in the following program on line 38 to a function call. The function is in the gameobjects module and the there's an error there as well on line 21. Here's the code.

Code:

background_image_filename = 'sushiplate.jpg'
sprite_image_filename = 'fugu.png'

import pygame
from pygame.locals import *
from sys import exit
from gameobjects import Vectory2

pygame.init()

screen = pygame.display.set_mode((640, 480), 0, 32)
background = pygame.image.load(sprite_image_filename).convert_alpha()

clock = pygame.time.Clock()

sprite_pos = Vectory2(200, 150)
sprite_speed = 300.

while True:
    
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
            
    pressed_key = pygame.key.get_pressed()
    
    key_direction = Vectory2(0, 0)
    
    if pressed_key[K_LEFT]:
        key_direction.x = -1
    elif pressed_key[K_RIGHT]:
        key_direction.x = + 1
    if pressed_key[K_UP]:
        key_direction.y = - 1
    elif pressed_key[K_DOWN]:
        key_direction.y = + 1
        
    key_direction.normalize()
    
    screen.blit(background, (0,0))
    screen.blit(sprite, sprite_pos)
    
    time_passed = clock.tick(30)
    time_passed_seconds = time_passed / 1000.0
    
    sprite_pos += key_direction * sprite_speed * time_passed_seconds
    
    pygame.display.update()

import math

class Vectory2(object):
    
    def __init__(self, x = 0.0, y = 0.0):
        self.x = x
        self.y = y
        
    def __str__(self):
        return "(%s, %s)" % (self.x, self.y)
    
    @staticmethod
    def from_points(P1, P2):
        return Vectory2(P2[0] - P1[0], P2[1] - P1[1])
    
    def get_magnitude(self):
        return math.sqrt(self.x**2 + self.y**2)
    
    def normalize(self):
        magnitude = self.get_magnitude()
        self.x /= magnitude
        self.y /= magnitude
        
    # rhs stands for right hand side
    def __add__(self, rhs):
        return Vectory2(self.x + rhs.x, self.y + rhs.y)

Thanks for any and all help.

Dani AI

Generated

As already pointed out, the crash is a classic divide-by-zero when normalizing the zero vector. Normalizing should either be guarded (so it does nothing for a zero-length vector) or replaced by a method that returns a safe default. ’s suggestion to add print/asserts is a good quick way to confirm when the direction is (0,0) before any fix is applied.

A safe in-place normalize that avoids ZeroDivisionError and tolerates floating-point noise:

import math

EPS = 1e-8

def normalize(self):
    mag = self.get_magnitude()
    if mag <= EPS:
        return self        # leave as-is (or choose a default unit vector)
    self.x /= mag
    self.y /= mag
    return self

An alternative is a non-mutating normalized() that returns a new vector (often easier to reason about):

def normalized(self):
    mag = self.get_magnitude()
    if mag <= 1e-8:
        return Vectory2(0.0, 0.0)
    return Vectory2(self.x / mag, self.y / mag)

Other practical notes tied to the thread:

  • Call normalize only when there is input (e.g., check magnitude > 0 before calling) so the program doesn’t perform needless work when no keys are pressed.
  • Add scalar multiplication so key_direction * speed works cleanly:
def __mul__(self, scalar):
    return Vectory2(self.x * scalar, self.y * scalar)
__rmul__ = __mul__
  • Verify image variables in the main script: ensure the sprite image is actually loaded into the name used when blitting (the code currently blits a sprite name that isn’t shown being created).
  • Keep debugging prints or assertions in place until movement behaves as expected; once stable, remove or replace them with logging.

These changes make the vector class robust and prevent the ZeroDivisionError without hiding other bugs (like missing sprite initialization or missing operator overloads).

Recommended Answers

All 4 Replies

The only potential error that I see in line 21 in is division by zero if x and y are both 0 in a Vectory2 instance. Why don't you post the exception traceback ? A bug in your code is that after the sequence with the keys in lines 29-36, the key_direction could very well be zero.

put in print or assert statements to get values of variables at point of error. You did not include image files to run your code.

ZeroDivisionError: float division
File "/home/developer/Projects/Beginning Game Development/Chapter 4/", line 38, in <module>
key_direction.normalize()
File "/home/developer/Projects/Beginning Game Development/Chapter 4/", line 21, in normalize
self.x /= magnitude

The problem is that key_direction is (0,0) initially. You can't normalize the null vector. You could start with (1,0), or choose a random angle a in [0, 2*pi] and start with (cos(a), sin(a)).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.