Python Forum
[PyGame] Creating multiple instances in State Machine.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Creating multiple instances in State Machine.
#1
My Starcon2 clone is coming along, but I need to figure a way to create multiple instances of my "star_system" and "planetscreen" state classes.

I have a random star map, and I would like each of these stars to have an individual "star_system" associated with it. And within a star system I need each planet to be its own instance of a "planet" class.

I'm going to assume that when I switch states to one of these I need to pass individualized information (ie, star name, star type, planet type, etc.) to the state machine but how to do this eludes me.

So, I want figure out how to go from this:
class Starmap(States):
    def __init__(self, screenrect):
        States.__init__(self)
        self.next = 'menu'
        self.all_sprites = pygame.sprite.Group()
        self.stations = pygame.sprite.Group()
        self.selectors = pygame.sprite.Group()
        self.selector = Map_selector()
        self.selectors.add(self.selector)
        self.all_sprites.add(self.selector)
        self.station = Space_station()
        self.all_sprites.add(self.station)
        self.stations.add(self.station)
        self.stars = pygame.sprite.Group()
        self.draw_stars()
        self.popup = Data_popup()
        self.all_sprites.add(self.popup)
        
    def cleanup(self):
        print('cleaning up Game state stuff')
    def startup(self):
        print('starting Game state stuff')
    def get_event(self, keys):
        
        starhit = pygame.sprite.spritecollide(self.selector, self.stars, False, False)
        keys = pygame.key.get_pressed()  
        vx, vy = 0, 0
        
        if keys[pygame.K_LEFT]: 
            vx = -selector_speed
        if keys[pygame.K_RIGHT]: 
            vx = selector_speed
        if keys[pygame.K_UP]: 
            vy = -selector_speed
        if keys[pygame.K_DOWN]:
            vy = selector_speed
        if vx != 0 and vy != 0:
            vx *= 0.7071
            vy *= 0.7071
        self.selector.rect.centerx += vx 
        self.selector.rect.centery += vy
        if keys[pygame.K_q]:
            self.done = True
        if keys[pygame.K_w]: 
            print(starhit)
            self.next = "star_system"
            for hit in starhit:
                print
                location = hit.name
                print(location)
                self.done = True
        
    def draw_stars(self):
        for star in range(1, 10):
            star = Stars()
            star.rect.centerx += random.randrange(-(width/2 +5), (width/2-5))
            star.rect.centery += random.randrange(-(height/2 +5), (height/2-5))
            self.stars.add(star)
            self.all_sprites.add(star)
            hits = pygame.sprite.groupcollide(self.stations, self.stars, False, True)   
       
    def update(self, screen, keys, dt):
        self.get_event(keys)
        self.all_sprites.update(self)
        self.draw(screen)
          
    def draw(self, screen):
        screen.fill(black)
        text_surf = pygame.Surface((300, 60))
        text_surf.fill(grey)
        draw_text(text_surf, "Arrows to select destination", 25, 5, 5)
        draw_text(text_surf, "Press ""w"" to Warp", 25, 5, 30)
        self.selectors.draw(screen)
        self.all_sprites.draw(screen)


To individualized instances of this:
class Star_system(States):
    
    def __init__(self, screenrect):
        States.__init__(self)
        self.next = 'menu'
        self.all_sprites = pygame.sprite.Group()
        self.ships = pygame.sprite.Group() 
        self.ship = Ship((300, 580))
        self.all_sprites.add(self.ship)
        self.ships.add(self.ship)
        self.parent_star = pygame.sprite.Group()
        self.planets = pygame.sprite.Group() 
        self.star = Star_RedDwarf()
        self.all_sprites.add(self.star)
        self.orbit_prompt = Orbit_prompt()
        self.all_sprites.add(self.orbit_prompt)
        number_of_planets = get_planet_number()
        current_velocity = pygame.Vector2(self.ship.velocity)
        velocity = "x: {:.3f}, y: {:.3f}"     
        for i in range(number_of_planets):
            planet = Planet(self)
            self.all_sprites.add(planet)
            self.planets.add(planet)

        current_velocity = pygame.Vector2(self.ship.velocity)
        velocity = "x: {:.3f}, y: {:.3f}"
        font = pygame.font.Font(None, 28)
        text = Text(velocity.format(0, 0), font, pygame.Color('white'), (10, 10))
    def cleanup(self):
        pass
    def startup(self):
        print("starting star system")   
    def update(self, screen, keys, dt):
        if keys[pygame.K_s]:
            self.next = "starmap"
            self.done = True
        hits = pygame.sprite.groupcollide(self.planets, self.ships, False, False)    
        
        for hit in hits:
            
            self.orbit_prompt.image.fill(yellow)
            self.orbit_prompt.rect.centerx = hit.rect.centerx + 20
            self.orbit_prompt.rect.centery = hit.rect.centery + 20
            draw_text(self.orbit_prompt.image, "Enter Orbit?", 12, 5, 5)
            draw_text(self.orbit_prompt.image, "Press Space", 12, 5, 20)
            if keys[pygame.K_SPACE]:
                self.next = "planetscreen"
                self.done = True
        if not hits:
            
            self.orbit_prompt.rect.x = 1000 
        self.all_sprites.update(screen, keys, dt)
        self.draw(screen)
    def draw(self, screen):
        screen.fill(black)
        
        for sprite in self.planets:  
            pygame.draw.circle(screen, sprite.orbit_color, (300, 300), sprite.dist, 1)
        draw_textw(screen, "s for starmap", 30, 100, 500)
        self.all_sprites.draw(screen)
I think the key lays in adding parameters/arguments to here, but unsure:
 self.state_dict = {
            'Start_screen': Start_screen(self.screen_rect), ## is it a matter of adding "name"
            'starmap': Starmap(self.screen_rect),           ## and "type" here?
            'planetscreen': Planet_screen(self.screen_rect),
            'landerstate': Landerstate(self.screen_rect),
            'star_system' : Star_system(self.screen_rect)
        }


The program works well going from starmap to star_system, to planet, but there is obviously only one of each of these per game start.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] Music starts too early in state machine michael1789 2 2,181 Feb-27-2020, 06:16 PM
Last Post: michael1789

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020