예제 #1
0
 def __init__(self,
              level_name,
              player,
              static_world_components,
              dynamic_world_components,
              background=None,
              level_size=None,
              camera_type=None):
     if level_size == None:
         level_size = background.size
     self.background = background
     self.size = level_size
     self.name = level_name
     # a dictionary with all image related game components
     self.player = player
     self.characters = [
     ]  # starts empty; is filled by npc, and the player(s)
     self.npc = pygame.sprite.Group()
     self.static_components = static_world_components  # image parts (e.g. background, ground)
     self.dynamic_components = dynamic_world_components  # image parts (e.g. swings, moving objects, bullets)
     self.components = [] + self.static_components + self.dynamic_components  # redundant list; fast requesting component
     self.add_character(player)
     # build the static game world
     self.image, self.rect = self.build_background(
         level_size,
         background=background,
         static_components=self.static_components)
     if camera_type is not None:
         self.camera = Camera(camera_type, player.rect,
                              level_size)  # the screen view
         # todo: decide on who should hold the camera
         graphics_handler.set_camera(
             self.camera
         )  # makes it possible to blit directly to the graphics handler
     else:
         self.camera = None
     self.freeze = False  # freezes all updates to components
     if INFO:
         print("[LV] image '{}' loaded".format(level_name))
     self.killed_monster = 0
예제 #2
0
scene = loading.load("test_map03")

chest = objects.getObjectsOfType(Chest)[0]
chest._items = [Item("Potion"), Item("Potion"), Item("Book")]

animTile = GameObject(z = 10, position = Vector2(0, 50))
animTile.sprite = sprite2.loadSpriteAnimation("player_idle")
animTile.play("player_idle")

_player = objects.getObjectsOfType(player.Player)[0]
_player.sprite = sprite2.loadSpriteAnimation("eggy")
_player.play("eggy")

#####
camera = Camera(15)
camera.setTarget(player.getPlayer())

fps_delay = 60 #Show fps every second
fps_delta = 0

while True:
    inputcontrol.evaluate(pygame.event.get())
    physics.solve(objects.getObjectsOfType(Entity))
    camera.render(gameScreen)
    ui.render(gameScreen)
    scaled_display = pygame.transform.scale(gameScreen, (SCREENWIDTH * SCALEFACTOR, SCREENHEIGHT * SCALEFACTOR))
    display.blit(scaled_display, (0, 0))
    pygame.display.update()
    clock.tick(60)
예제 #3
0
from pygame.locals import *
from pygame import *
from graphics import Camera
from pygame.math import Vector2
from gameobject import GameObject

pygame.init()

display = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
pygame.display.set_caption("Ultimate Pong")
clock = pygame.time.Clock()

fps_delay = 60
fps_delta = 0

camera = Camera()

background = GameObject(position=Vector2(0, 0),
                        scale=Vector2(SCREENWIDTH, SCREENHEIGHT))
background.colorize(pygame.Color(255, 255, 255))

ball = GameObject(position=Vector2(40, 40))
ball.colorize(pygame.Color(255, 0, 0))

while True:
    #TODO: Move inputs into a custom class and handle with single function call
    for event in pygame.event.get():
        if event.type == QUIT:
            print("Closing game...")
            pygame.quit()
            sys.exit(0)
예제 #4
0
class Level:
    """A class with image resources, and helper functions"""
    def __init__(self,
                 level_name,
                 player,
                 static_world_components,
                 dynamic_world_components,
                 background=None,
                 level_size=None,
                 camera_type=None):
        if level_size == None:
            level_size = background.size
        self.background = background
        self.size = level_size
        self.name = level_name
        # a dictionary with all image related game components
        self.player = player
        self.characters = [
        ]  # starts empty; is filled by npc, and the player(s)
        self.npc = pygame.sprite.Group()
        self.static_components = static_world_components  # image parts (e.g. background, ground)
        self.dynamic_components = dynamic_world_components  # image parts (e.g. swings, moving objects, bullets)
        self.components = [] + self.static_components + self.dynamic_components  # redundant list; fast requesting component
        self.add_character(player)
        # build the static game world
        self.image, self.rect = self.build_background(
            level_size,
            background=background,
            static_components=self.static_components)
        if camera_type is not None:
            self.camera = Camera(camera_type, player.rect,
                                 level_size)  # the screen view
            # todo: decide on who should hold the camera
            graphics_handler.set_camera(
                self.camera
            )  # makes it possible to blit directly to the graphics handler
        else:
            self.camera = None
        self.freeze = False  # freezes all updates to components
        if INFO:
            print("[LV] image '{}' loaded".format(level_name))
        self.killed_monster = 0

    @staticmethod
    def build_background(level_size,
                         background=None,
                         static_components=None,
                         colour=(255, 150, 0)):
        if static_components is None:
            static_components = []

        level = pygame.Surface(level_size)
        level.fill(colour)
        level_rect = level.get_rect()
        if background is not None:
            level.blit(background.image, background.rect)
            if INFO:
                print('[LV] Background blitted in build: {}'.format(
                    background.rect))

        for placement in [Background,
                          Ground]:  # first blit Background, afterwards Ground
            for component in static_components:
                # if not self.level_rect.contains(component.rect): continue  # only if component fits in level
                if type(component) == placement:
                    level.blit(component.image.convert_alpha(), component.rect)
        if INFO:
            print("image surface created: {}".format(level))
        return level, level_rect

    # game component management)
    def add_world_component(self, world_component):
        self.static_components.append(world_component)
        if DEBUG:
            print("added image to game world: " + repr(world_component.image))
        self.image.blit(world_component.image, world_component.rect)
        self.components.append(world_component)

    # when adding a dynamic level component to the level, this method should be used exclusively
    def add_component(self, component):
        self.dynamic_components.append(component)
        self.components.append(component)
        component.level = self  # can't get sprite groups to work

    def del_component(self, component):
        if type(component) == Player:
            self.player = None
        try:
            del self.dynamic_components[self.dynamic_components.index(
                component)]  # component should have __eq__ overridden
        except ValueError as ex:
            if WARNING:
                print(
                    f"[LL] couldn't find component in dynamic components list {component}"
                )
        try:
            del self.components[self.components.index(component)]
        except ValueError as ex:
            if WARNING:
                print(
                    f"[LL] couldn't find component in components list {component}"
                )

    def add_character(self, character):
        self.characters.append(character)
        if character.TYPE == 'Monster':
            character.enemy = self.player
        character.level = self
        #self.npc.add(character)

    def del_character(self, character):
        index = self.characters.index(character)
        del self.characters[index]
        if character is self.player:
            self.player = None
        if isinstance(character, Monster):
            self.killed_monster += 1

    def del_component_index(self):  # maybe implement this
        pass

    def get_dynamic_components(self):
        """builds a (flat) list with all dynamic game component"""
        return [x for x in self.dynamic_components]

    def get_game_components(self):
        """Builds a new list with all static and dynamic components"""
        # first get the static components, as these will be blitted over by the dynamic ones
        return [x for x in self.components]

    def update(self, dt):
        """update all game components in the current level (does not checks for collisions)"""
        if self.player is None:
            self.end()
        if self.freeze:
            if self.player:

                self.add_component(
                    Text("you can unfreeze the screen with 'f'",
                         (self.camera.rect.centerx - 80,
                          self.camera.rect.centery - 160), (200, 200),
                         max_time=1,
                         font_size=25))
            return
        for character in self.characters:
            if character.is_alive():
                character.update(dt)
            else:
                self.del_character(character)
        for component in self.dynamic_components:
            component.update(dt)
        # update camera as last
        if self.camera and self.player:
            self.camera.update(self.player.rect)
        if len(self.characters
               ) <= 1:  # there should always be one monster in the game
            self.add_character(
                Schagel((random.randint(0, self.size[0]), self.size[1] / 2),
                        (58, 52)))

    def check_level_finished(self):
        if self.killed_monster >= 8:
            return True
        return False

    # collision detection per entity that the function is called with
    @staticmethod
    def detect_collision(entity, components):
        if entity.ground:
            return
        for component in components:
            if pygame.sprite.collide_rect(entity, component):
                if component:  # makes it acceptable to have None in components
                    if DEBUG:
                        print("[CD] ground collision!")
                    return component
                else:
                    if DEBUG:
                        print("[CD] unknown collision: {}".format(component))

    @staticmethod
    def detect_entity_collision(entity):
        pass

    # returns None, or the first found ground
    @staticmethod
    def find_type_collision(entity, components, component_type):
        for component in components:
            if pygame.sprite.collide_rect(
                    entity, component) and type(component) == component_type:
                if DEBUG:
                    print("[CD] {} collision!".format(component_type))
                return component

    # calls on_collision on all entities
    @staticmethod
    def detect_type_collisions(entities, components, component_types):
        """detects the collision between all static components, of one or multiple types, and 'entities';
        calls on_collision on every entity"""
        for entity in entities:
            for component in components:
                if type(component
                        ) in component_types and pygame.sprite.collide_rect(
                            entity, component):
                    if DEBUG:
                        print(f"[CD] collision: '{entity}', '{component}'!")
                    component.on_collision(entity)
                    if isinstance(component, PhysicsEntity):
                        entity.on_collision(component)

    def detect_characters_ground(self):
        for character in self.characters:
            for component in self.static_components:
                if type(component) in [Ground, BuildingBlock
                                       ] and pygame.sprite.collide_rect(
                                           character, component):
                    if DEBUG:
                        print(
                            f"[CD] ground collision: '{character}', '{component}'!"
                        )
                    character.on_collision(component)
                    break
                character.ground = None

    # checks collision between all characters with zero double-checks
    def detect_character_collisions(self):
        """Check collision between every character once.
         Calls the collision method on each with as argument the other"""
        temp = [character for character in self.characters]
        for character0 in self.characters:
            for character1 in temp:
                if character0 != character1 and pygame.sprite.collide_rect(
                        character0, character1):
                    character0.on_collision(character1)
                    character1.on_collision(character0)
                    if DEBUG:
                        print(
                            f"[LV] collision between: {character0} and {character1}"
                        )
            del temp[0]

    def detect_characters_out_of_bound(self):
        for character in self.characters:
            if not pygame.sprite.collide_rect(character, self):
                self.del_character(character)
                if DEBUG:
                    print(f"char out of bound: {character}")
            if 0 > character.rect.left:
                character.rect.left = 0
            elif character.rect.left > self.size[0]:  # level x size
                character.rect.right = self.size[0]

    # check collisions for affected parties
    def detect_collisions(self):
        self.detect_characters_out_of_bound()
        self.detect_character_collisions()
        self.detect_characters_ground()
        self.detect_type_collisions(self.characters, self.dynamic_components,
                                    [Vial])
        self.detect_type_collisions(self.dynamic_components,
                                    self.static_components, [Ground])

    # displays all image components from back- to foreground
    def display(self):
        """calls display on every component;
        blitting them, and adding their rectangle to a dirty rectangles list"""
        # first put the background on the display
        if self.camera is None:
            camera_rect = None
        else:
            camera_rect = self.camera.rect

        graphics_controller.blit(self.image, self.rect,
                                 self.camera.rect)  # display level base image
        for dynamic_component in self.dynamic_components:  # things like throw-ables
            dynamic_component.display(camera_rect)
        for character in self.characters:  # player and NPCs
            character.display(camera_rect)
        for static_component in self.static_components:  # foreground is the last to be displayed
            if type(static_component) == ForeGround:
                static_component.display(camera_rect)

    def end(self):
        self.freeze = True
        self.add_component(
            Text("End Of Game", (self.camera.rect.centerx, self.size[1] / 2),
                 (100, 50),
                 font_size=30))

    def __del__(self):
        graphics_handler.unset_camera()
        if INFO:
            print("[LL] image '{}' unloaded".format(self.name))
예제 #5
0
	def load(self):
		self.world_size = Size(3000, 3000)

		self.camera = Camera(self.size, self.world_size, 1000, 10)

		self._tool = None
		self.tool = None

		self.batch = graphics.Batch()
		self.background = CameraGroup(graphics.OrderedGroup(0), self.camera)
		self.foreground = CameraGroup(graphics.OrderedGroup(1), self.camera)
		self.playerg = CameraGroup(graphics.OrderedGroup(2), self.camera)
		self.world_ui = CameraGroup(graphics.OrderedGroup(3), self.camera)
		self.ui = graphics.OrderedGroup(2)

		self.space = Space()
		self.space.gravity = (0.0, 0.0)
		buffer = 100
		borders = Body()
		borders.position = (0, 0)
		left = Segment(borders, (-buffer, -buffer), (-buffer, self.world_size.height+buffer), buffer)
		bottom = Segment(borders, (-buffer, -buffer), (self.world_size.width+buffer, -buffer), buffer)
		right = Segment(borders, (self.world_size.width+buffer, self.world_size.height+buffer),
			(self.world_size.width+buffer, -buffer), buffer)
		top = Segment(borders, (self.world_size.width+buffer, self.world_size.height+buffer),
			(-buffer, self.world_size.height+buffer), buffer)
		self.space.add_static(left, bottom, right, top)

		self.stars = Stars(self.world_size, self.batch, self.background)

		self.asteroids = Asteroid.populate(50, 100, self.world_size, self.batch, self.foreground, self.space)

		if not self.asteroids:
			print("None of a particular resource on this asteroid belt, that'd be unfair. Trying again.")
			self.end(Main())
			return

		self.home_world = choice([asteroid for asteroid in self.asteroids if asteroid.position.y > self.world_size.height/4*3])
		self.home_world.type = "home"
		self.home_world.populated = True

		x, y = self.home_world.position
		self.camera.move(Vector(x-self.size.width/2, y-self.size.height/2))

		# Let's make stuff a bit more interesting.
		for asteroid in self.asteroids:
			if not asteroid.type == "home":
				asteroid.body.apply_impulse((triangular(-20000, 20000, 0), triangular(-20000, 20000, 0)))

		x, y = self.home_world.position
		self.player = Person(x+150, y+150, self.batch, self.playerg, self.space)
		self.mouse = x+150, y+150

		centre = Vector(self.size.width/2, self.size.height/2)
		image = centre_image(resource.image("logo.png"))
		self.logo = sprite.Sprite(image, centre.x, centre.y, batch=self.batch, group=self.ui)
		self.logo.opacity = 255
		self.fade = True
		self.faded = False

		planet = centre_image(resource.image("planet.png"))
		x = self.world_size.width/2
		y = planet.height/2
		self.planet_sprite = sprite.Sprite(planet, x, y, batch=self.batch, group=self.world_ui)
		self.win_box = BB(x-200, y-200, x+200, y+200)

		#self.tools = sorted([tool(self.space) for tool in Tool.__subclasses__()], key=attrgetter("order"), reverse=True)
		#self.buttons = {tool: Button(30, 30+number*50, tool.image, tool.description, self.use_tool(tool), self.ui, self.batch) for number, tool in enumerate(self.tools)}

		self.constraints = set()
예제 #6
0
class Main(Scene):

	FADE_SPEED = 75

	def load(self):
		self.world_size = Size(3000, 3000)

		self.camera = Camera(self.size, self.world_size, 1000, 10)

		self._tool = None
		self.tool = None

		self.batch = graphics.Batch()
		self.background = CameraGroup(graphics.OrderedGroup(0), self.camera)
		self.foreground = CameraGroup(graphics.OrderedGroup(1), self.camera)
		self.playerg = CameraGroup(graphics.OrderedGroup(2), self.camera)
		self.world_ui = CameraGroup(graphics.OrderedGroup(3), self.camera)
		self.ui = graphics.OrderedGroup(2)

		self.space = Space()
		self.space.gravity = (0.0, 0.0)
		buffer = 100
		borders = Body()
		borders.position = (0, 0)
		left = Segment(borders, (-buffer, -buffer), (-buffer, self.world_size.height+buffer), buffer)
		bottom = Segment(borders, (-buffer, -buffer), (self.world_size.width+buffer, -buffer), buffer)
		right = Segment(borders, (self.world_size.width+buffer, self.world_size.height+buffer),
			(self.world_size.width+buffer, -buffer), buffer)
		top = Segment(borders, (self.world_size.width+buffer, self.world_size.height+buffer),
			(-buffer, self.world_size.height+buffer), buffer)
		self.space.add_static(left, bottom, right, top)

		self.stars = Stars(self.world_size, self.batch, self.background)

		self.asteroids = Asteroid.populate(50, 100, self.world_size, self.batch, self.foreground, self.space)

		if not self.asteroids:
			print("None of a particular resource on this asteroid belt, that'd be unfair. Trying again.")
			self.end(Main())
			return

		self.home_world = choice([asteroid for asteroid in self.asteroids if asteroid.position.y > self.world_size.height/4*3])
		self.home_world.type = "home"
		self.home_world.populated = True

		x, y = self.home_world.position
		self.camera.move(Vector(x-self.size.width/2, y-self.size.height/2))

		# Let's make stuff a bit more interesting.
		for asteroid in self.asteroids:
			if not asteroid.type == "home":
				asteroid.body.apply_impulse((triangular(-20000, 20000, 0), triangular(-20000, 20000, 0)))

		x, y = self.home_world.position
		self.player = Person(x+150, y+150, self.batch, self.playerg, self.space)
		self.mouse = x+150, y+150

		centre = Vector(self.size.width/2, self.size.height/2)
		image = centre_image(resource.image("logo.png"))
		self.logo = sprite.Sprite(image, centre.x, centre.y, batch=self.batch, group=self.ui)
		self.logo.opacity = 255
		self.fade = True
		self.faded = False

		planet = centre_image(resource.image("planet.png"))
		x = self.world_size.width/2
		y = planet.height/2
		self.planet_sprite = sprite.Sprite(planet, x, y, batch=self.batch, group=self.world_ui)
		self.win_box = BB(x-200, y-200, x+200, y+200)

		#self.tools = sorted([tool(self.space) for tool in Tool.__subclasses__()], key=attrgetter("order"), reverse=True)
		#self.buttons = {tool: Button(30, 30+number*50, tool.image, tool.description, self.use_tool(tool), self.ui, self.batch) for number, tool in enumerate(self.tools)}

		self.constraints = set()

	def use_tool(self, tool):
		"""For callback usage."""
		def f():
		  self.tool = tool
		return f

	@property
	def tool(self):
		return self._tool

	@tool.setter
	def tool(self, tool):
		if tool:
			if self._tool and not self._tool == tool:
				self._tool.end_selecting()
				self.buttons[self._tool].normal()
				self.window.set_mouse_cursor(self.window.get_system_mouse_cursor(self.window.CURSOR_DEFAULT))
				self.selecting = False
				self.selection = []
			self.window.set_mouse_cursor(self.window.get_system_mouse_cursor(self.window.CURSOR_CROSSHAIR))
			self.selecting = True
			self.buttons[tool].using()
		else:
			if self._tool:
				self._tool.end_selecting()
				self.buttons[self._tool].normal()
			self.window.set_mouse_cursor(self.window.get_system_mouse_cursor(self.window.CURSOR_DEFAULT))
			self.selecting = False
			self.selection = []
		self._tool = tool

	def key_pressed(self, symbol, modifiers):
		self.fade = True
		#self.camera.key_pressed(symbol)

	def key_released(self, symbol, modifiers):
		pass
		#self.camera.key_released(symbol)

	def mouse_pressed(self, x, y, key, modifiers):
		self.fade = True
		#for button in self.buttons.values():
		#	if button.point_over(x, y):
		#		button.callback()
		#		return
		if self.selecting:
			for asteroid in self.asteroids:
				clicked = self.camera.translate(x, y)
				if asteroid.point_over(*clicked):
					self.selection.append((asteroid, clicked))
					self.tool = self.tool.selection(self.selection, self.constraints)
					return
			self.tool = None
			return

	def mouse_motion(self, x, y, dx, dy):
		self.mouse = self.camera.translate(x, y)
		#for button in self.buttons.values():
	#		if button.point_over(x, y):
	#			button.on_mouse_over()
	#		else:
	#			button.on_mouse_leave()

	def mouse_drag(self, x, y, dx, dy, buttons, modifiers):
		if buttons & window.mouse.RIGHT:
			self.camera.mouse_dragged(dx, dy)

	def update(self, frame_time):
		self.constraints = {constraint for constraint in self.constraints if not constraint.update(self.batch, self.foreground)}
		if self.fade and not self.faded:
			self.logo.opacity -= Main.FADE_SPEED*frame_time
			if self.logo.opacity < 0:
				self.logo.opacity = 0
				del self.logo
				self.faded = True
		self.player.target = self.mouse
		self.player.update()
		x, y = self.player.body.position
		self.camera.x, self.camera.y = x-self.size.width/2, y-self.size.height/2
		self.camera.update(frame_time)
		self.space.step(1/60)
		if self.win_box.contains_vect(self.player.body.position):
			self.end(Win())

	def draw(self):
		self.batch.draw()
예제 #7
0
import objects
import inputcontrol
import loading
from graphics import Camera
from pygame.math import Vector2
import sys
from pygame.locals import *

if __name__ == "__main__":
    pygame.init()
    display = pygame.display.set_mode((960, 540))
    pygame.display.set_caption("Pygame Level Editor")

    clock = pygame.time.Clock()

    camera = Camera(15)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                import ctypes
                if ctypes.windll.user32.MessageBoxW(
                        0, "Any unsaved progress will be lost!",
                        "Are you sure?", 1) == 1:
                    print("Editor exit")
                    pygame.quit()
                    sys.exit()
            elif event.type == MOUSEMOTION:
                pygame.display.update()

        clock.tick(30)