[Pygame] laggy enemy kill

[Pygame] laggy enemy kill

Postby metulburr » Thu May 09, 2013 11:18 pm

when you hit an enemy it lags for a second or so. For some reaason i think it is upon creation of the new enemy that it lags as it happens when you first run it. I am not sure why it lags though?

Code: Select all
import pygame
import sys
import math
import random

def image_from_url(url):
    try:
        from urllib2 import urlopen
        from cStringIO import StringIO as inout
    except ImportError:
        from urllib.request import urlopen
        from io import BytesIO as inout
    myurl = urlopen(url)
    return inout(myurl.read())

class Projectile:
    limit = 3
    def __init__(self, loc):
        self.surf = pygame.Surface((5,10)).convert()
        self.surf.set_colorkey((255,0,255))
        self.surf.fill((255,255,255))
        self.rect = self.surf.get_rect()
        self.rect.center = loc
        self.mask = pygame.mask.from_surface(self.surf)
        self.speed = 8

class Enemy:
    count = 3
    def __init__(self, start_loc):
        link = 'http://i1297.photobucket.com/albums/ag23/metulburr/spaceship_enemy3_zpscfeb13bf.png'
        self.orig_image = pygame.image.load(image_from_url(link)).convert()
        self.orig_image = pygame.transform.scale(self.orig_image, (40,80))
        self.orig_image.set_colorkey((255,0,255))
        self.image = pygame.transform.rotate(self.orig_image, 180)
        self.mask = pygame.mask.from_surface(self.image)
        self.rect = self.image.get_rect()
        self.rect.center = start_loc
        self.bullets = []
        self.speed = 2
        self.is_hit = False
       
    def pos_towards_player(self, player_rect):
        '''get new coords towards player'''
        c = math.sqrt((player_rect.x - self.rect[0]) ** 2 + (player_rect.y - self.rect[1]) ** 2)
        try:
            x = (player_rect.x - self.rect[0]) / c
            y = (player_rect.y - self.rect[1]) / c
        except ZeroDivisionError:
            return (self.rect.x, self.rect.y)
        return (x,y)
       
    def destroy(self):
        ...
       
    def update(self, player_rect):
       
        if self.is_hit:
            self.destroy()
        if not self.is_hit:
            #move enemy towards player
            new_pos = self.pos_towards_player(player_rect)
            self.rect.x, self.rect.y = (self.rect.x + new_pos[0] * self.speed, self.rect.y + new_pos[1] * self.speed)
           
           


class Player:
    def __init__(self, start_loc):
        self.speed = 4

        link = 'http://i1297.photobucket.com/albums/ag23/metulburr/spaceship2_zps095c332a.png'
        self.orig_image = pygame.image.load(image_from_url(link)).convert()
        self.orig_image = pygame.transform.scale(self.orig_image, (40,80))
        self.orig_image.set_colorkey((255,0,255))

        self.image = pygame.transform.rotate(self.orig_image, 180)
        self.mask = pygame.mask.from_surface(self.image)
        self.rect = self.image.get_rect()
        self.rect.center = start_loc

        self.bullets = []

    def move(self, x, y):
        self.rect[0] += x * self.speed
        self.rect[1] += y * self.speed


class Control:
    def __init__(self):
        self.screensize = (800,600)
        self.screen = pygame.display.set_mode(self.screensize)
        self.screenrect = self.screen.get_rect()
        self.clock = pygame.time.Clock()
        self.player = Player((0,600))
        #self.enemy = Enemy((800,0))
       
        self.enemies = []


        self.mainloop()

    def mainloop(self):
        run = True
        while run:
            self.screen.fill((0,0,0))

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        if len(self.player.bullets) <= Projectile.limit:
                            self.player.bullets.append(Projectile(self.player.rect.center))

            self.update()
            pygame.display.flip()
            self.clock.tick(60)

    def update(self):
        self.keys = pygame.key.get_pressed()
       
        for obj in self.enemies:
            obj.update(self.player.rect)
           
       
        #make new enemies
        print(len(self.enemies))
        if len(self.enemies) <= Enemy.count:
            self.enemies.append(Enemy((random.randint(1,800),-100)))

        if self.player.bullets:
            for obj in self.player.bullets:
                self.screen.blit(obj.surf, obj.rect)
                obj.rect[1] -= obj.speed

                #did obj move off screen
                if obj.rect[1] < 0:
                    self.player.bullets.remove(obj)
                #did obj hit enemy rect
                for enem in self.enemies:
                    if obj.rect.colliderect(enem.rect):
                        offset_x =  enem.rect.x - obj.rect.x
                        offset_y =  enem.rect.y - obj.rect.y
                        #did object hit enemy mask
                        if obj.mask.overlap(enem.mask, (offset_x, offset_y)):
                            self.player.bullets.remove(obj)
                            self.enemies.remove(enem)
                            enem.is_hit = True
                       

        if self.keys[pygame.K_UP]:
            self.player.move(0,-1)
        if self.keys[pygame.K_DOWN]:
            self.player.move(0,1)
        if self.keys[pygame.K_RIGHT]:
            self.player.move(1,0)
        if self.keys[pygame.K_LEFT]:
            self.player.move(-1,0)

        self.player.rect.clamp_ip(self.screenrect) #make sure rect does not go outside of screen
        for obj in self.enemies:
            if not obj.is_hit:
                self.screen.blit(obj.image, obj.rect)
        #if not self.enemy.is_hit:
         #   self.screen.blit(self.enemy.image, self.enemy.rect)
        self.screen.blit(self.player.image, self.player.rect)

app = Control()
pygame.quit();sys.exit()
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1416
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] laggy enemy kill

Postby Mekire » Thu May 09, 2013 11:30 pm

Well first off I can see that you are loading your Enemy image every time you create a new Enemy inside its __init__, rather than loading the image once and just using a reference to that loaded image every new enemy. I'm not sure if this is the cause of your delay, but it certainly isn't helping. I'll take a closer look and get back to you.

-Mek
User avatar
Mekire
 
Posts: 987
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: [Pygame] laggy enemy kill

Postby metulburr » Thu May 09, 2013 11:41 pm

ok i again figured it out. I was loading them from the url upon each creation which is obviously bad, i was doing it the same as with the player, but since the player only gets loaded once and its just testing, then whatever.

Code: Select all
import pygame
import sys
import math
import random

def image_from_url(url):
    try:
        from urllib2 import urlopen
        from cStringIO import StringIO as inout
    except ImportError:
        from urllib.request import urlopen
        from io import BytesIO as inout
    myurl = urlopen(url)
    return inout(myurl.read())

class Projectile:
    limit = 3
    def __init__(self, loc):
        self.surf = pygame.Surface((5,10)).convert()
        self.surf.set_colorkey((255,0,255))
        self.surf.fill((255,255,255))
        self.rect = self.surf.get_rect()
        self.rect.center = loc
        self.mask = pygame.mask.from_surface(self.surf)
        self.speed = 8

class Enemy:
    count = 3
    def __init__(self, start_loc, orig_image):
        self.orig_image = orig_image
        #link = 'http://i1297.photobucket.com/albums/ag23/metulburr/spaceship_enemy3_zpscfeb13bf.png'
        #self.orig_image = pygame.image.load(image_from_url(link)).convert()
        self.orig_image = pygame.transform.scale(self.orig_image, (40,80))
        self.orig_image.set_colorkey((255,0,255))
        self.image = pygame.transform.rotate(self.orig_image, 180)
        self.mask = pygame.mask.from_surface(self.image)
        self.rect = self.image.get_rect()
        self.rect.center = start_loc
        self.bullets = []
        self.speed = 2
        self.is_hit = False
       
    def pos_towards_player(self, player_rect):
        '''get new coords towards player'''
        c = math.sqrt((player_rect.x - self.rect[0]) ** 2 + (player_rect.y - self.rect[1]) ** 2)
        try:
            x = (player_rect.x - self.rect[0]) / c
            y = (player_rect.y - self.rect[1]) / c
        except ZeroDivisionError:
            return (self.rect.x, self.rect.y)
        return (x,y)
       
    def destroy(self):
        ...
       
    def update(self, player_rect):
        if not self.is_hit:
            #move enemy towards player
            new_pos = self.pos_towards_player(player_rect)
            self.rect.x, self.rect.y = (self.rect.x + new_pos[0] * self.speed, self.rect.y + new_pos[1] * self.speed)
           
           


class Player:
    def __init__(self, start_loc):
        self.speed = 4

        link = 'http://i1297.photobucket.com/albums/ag23/metulburr/spaceship2_zps095c332a.png'
        self.orig_image = pygame.image.load(image_from_url(link)).convert()
        self.orig_image = pygame.transform.scale(self.orig_image, (40,80))
        self.orig_image.set_colorkey((255,0,255))

        self.image = pygame.transform.rotate(self.orig_image, 180)
        self.mask = pygame.mask.from_surface(self.image)
        self.rect = self.image.get_rect()
        self.rect.center = start_loc

        self.bullets = []

    def move(self, x, y):
        self.rect[0] += x * self.speed
        self.rect[1] += y * self.speed


class Control:
    def __init__(self):
        self.screensize = (800,600)
        self.screen = pygame.display.set_mode(self.screensize)
        self.screenrect = self.screen.get_rect()
        self.clock = pygame.time.Clock()
        self.player = Player((0,600))
        #self.enemy = Enemy((800,0))
        link = 'http://i1297.photobucket.com/albums/ag23/metulburr/spaceship_enemy3_zpscfeb13bf.png'
        self.enemy_image = pygame.image.load(image_from_url(link)).convert()
       
        self.enemies = []


        self.mainloop()

    def mainloop(self):
        run = True
        while run:
            self.screen.fill((0,0,0))

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        if len(self.player.bullets) <= Projectile.limit:
                            self.player.bullets.append(Projectile(self.player.rect.center))

            self.update()
            pygame.display.flip()
            self.clock.tick(60)

    def update(self):
        self.keys = pygame.key.get_pressed()
       
        #for obj in self.enemies:
        #    obj.update(self.player.rect)
           
       
        #make new enemies
        #print(len(self.enemies))
       
        if len(self.enemies) <= Enemy.count:
            self.enemies.append(Enemy((random.randint(1,800),-100), self.enemy_image))
           

        if self.player.bullets:
            for obj in self.player.bullets:
                self.screen.blit(obj.surf, obj.rect)
                obj.rect[1] -= obj.speed

                #did obj move off screen
                if obj.rect[1] < 0:
                    self.player.bullets.remove(obj)
                #did obj hit enemy rect
                for enem in self.enemies:
                    if obj.rect.colliderect(enem.rect):
                        offset_x =  enem.rect.x - obj.rect.x
                        offset_y =  enem.rect.y - obj.rect.y
                        #did object hit enemy mask
                        if obj.mask.overlap(enem.mask, (offset_x, offset_y)):
                            self.player.bullets.remove(obj)
                            self.enemies.remove(enem)
                            enem.is_hit = True
   
                       

        if self.keys[pygame.K_UP]:
            self.player.move(0,-1)
        if self.keys[pygame.K_DOWN]:
            self.player.move(0,1)
        if self.keys[pygame.K_RIGHT]:
            self.player.move(1,0)
        if self.keys[pygame.K_LEFT]:
            self.player.move(-1,0)

        self.player.rect.clamp_ip(self.screenrect) #make sure rect does not go outside of screen
        for obj in self.enemies:
            obj.update(self.player.rect)
            if not obj.is_hit:
                self.screen.blit(obj.image, obj.rect)
        #if not self.enemy.is_hit:
         #   self.screen.blit(self.enemy.image, self.enemy.rect)
        self.screen.blit(self.player.image, self.player.rect)

app = Control()
pygame.quit();sys.exit()
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1416
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: [Pygame] laggy enemy kill

Postby metulburr » Thu May 09, 2013 11:42 pm

oh didnt even see you post, Mekire. Yeah that was the problem. Forgot i was loading it from the url every time
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1416
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY


Return to Game Development

Who is online

Users browsing this forum: No registered users and 3 guests