Using a function closes pygame window

Viewed 99

The following is the String class. Using the draw function from this class in my main loop immediately closes the game without any errors and as long i dont include it, the game runs fine. It does give me the following warning.

Warning (from warnings module):
  File "C:\Users\rahul\OneDrive\Documents\A level python codes\shootingGame.py", line 44
    D.blit(self.player, (self.pos[0], self.pos[1]))
DeprecationWarning: an integer is required (got type float).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.

import math, sys, os, pygame
from pygame.locals import *

pygame.init()

win = pygame.display
D = win.set_mode((1200, 600))

class String:
    def __init__(self, x, y):
        self.pos = [x, y]
        self.dx = 0
        self.dy = 0
        self.string = pygame.Surface((1, 1)).convert_alpha()
        self.string.fill((0, 255, 0))

    def draw(self):
        angle = pygame.transform.rotate(self.string, (player.orbital_angle))
        length = math.hypot(self.dx, self.dy)
        self.string = pygame.Surface((3, length))
        D.blit(angle, (self.pos[0], self.pos[1]))

string = String(600, 300)
While True:
    string.draw()

I initially had everything in draw function in differnet functions but it got a bit messy while debugging.Specifically, it is the last two lines in draw() that's causing the window to crash i.e

self.string = pygame.Surface((3, length))
D.blit(angle, (self.pos[0], self.pos[1]))
1 Answers

The position (dest) argument to pygame.Surface.blit() is ought to be a tuple of 2 integral numbers.
In your case self.pos[0] and/or self.pos[1] seems to be a floating point number.

You can get rid of the warning by rounding the floating point coordinates to integral coordinates (round):

D.blit(self.player, (round(self.pos[0]), round(self.pos[1])))

For the sake of completeness it has to be mentioned that the argument can also be a rectangle. A tuple with the 4 components (left, top, width, height).


Furthermore you have create a Surface with an integral length and you have to rotate the surface after it is (re)created:

class String:
    # [...]
   
    def draw(self):

        # compute INTEGRAL length        
        length = math.hypot(self.dx, self.dy)
        length = max(1, int(length))

        # create surface
        self.string = pygame.Surface((1, length)).convert_alpha()
        self.string.fill((0, 255, 0))

        # roatet surface
        angle = pygame.transform.rotate(self.string, player.orbital_angle)

        # blit rotated surface
        D.blit(angle, (round(self.pos[0]), round(self.pos[1])))
Related