Beispiel #1
0
class Element(object):
    exist = True

    def __init__(self, x_co, y_co, w_co, h_co, vx_co, vy_co, mass, level_co,
                 c_co):
        """
        initialize everything
        x_co, y_co: the center coordinates.
        w_co, h_co: the width and height.
        vx_co, vy_co: speed to 2 coordinates.
        c_co: coefficient of restitution
        """
        self.w = w_co
        self.h = h_co
        self.vx = vx_co
        self.vy = vy_co
        self.mylevel = level_co
        self.graphics = Graphics(self)
        self.m = mass
        self.c = c_co
        self.update(x_co, y_co)
        self.af = 0.9

    def set_exist(self, x):
        self.exist = x

    def update(self, x1, y1):
        """
        update the position of element
        """
        self.x = x1
        self.y = y1
        self.left = self.x - self.w / 2.0
        self.right = self.x + self.w / 2.0
        self.top = self.y - self.h / 2.0
        self.bottom = self.y + self.h / 2.0

    def in_inter(self, x, a, b):
        """
        return true when x is inside the interval [a, b]
        """
        assert a <= b, 'Invalid interval'
        if x >= a and x <= b:
            return True
        return False

    def touch(self, elem):
        """
        return true if the two elements are overlapped by the other
        """
        gapright = self.right - elem.left
        gapleft = elem.right - self.left
        gaptop = -self.top + elem.bottom
        gapbottom = -elem.top + self.bottom
        if gapleft > 0 and gapright > 0 and gaptop > 0 and gapbottom > 0:
            if min(gapleft, gapright) < min(gaptop, gapbottom):
                #collision horizontal
                if gapleft < gapright:
                    return 3
                else:
                    return 1
            else:
                #collision vertical
                if gaptop < gapbottom:
                    return 2
                else:
                    return 4
        else:
            return 0

    def touch_ammount(self, elem):
        gapright = self.right - elem.left
        gapleft = elem.right - self.left
        gaptop = -self.top + elem.bottom
        gapbottom = -elem.top + self.bottom
        direction = self.touch(elem)
        if direction == 0:
            return 0
        elif direction == 1:
            return gapright
        elif direction == 2:
            return gaptop
        elif direction == 3:
            return gapleft
        elif direction == 4:
            return gapbottom
        else:
            assert False, "invalid direction"

    def move(self, elem):
        """
          move something out of another element under the presumption that those two elements are overlapped
          return nothing
        """
        direction = self.touch(elem)
        ammount = self.touch_ammount(elem)
        if direction == 0:
            return
        elif direction == 1:
            elem.x += ammount
        elif direction == 2:
            elem.y -= ammount
        elif direction == 3:
            elem.x -= ammount
        elif direction == 4:
            elem.y += ammount
        else:
            assert False, "invalid direction"

        elem.update(elem.x, elem.y)

    def phy_for(self, va, vb, ma, mb, coef):
        """
        take in objects a and b's speed and mass and return the speed for object b
        coef is the coefficient of restitution which is the average of the c of two elements
        """
        v = (coef * ma * (va - vb) + ma * va + mb * vb) / (ma + mb)
        return v

    def collide(self, elem):
        """
        modify the other element's speed; return nothing
        """
        direction = self.touch(elem)
        coef = (self.c + elem.c) / 2
        if direction == 1 or direction == 3:
            if elem.vy > 0:
                elem.vy = max(0, elem.vy - self.af * abs(elem.vx))
            else:
                elem.vy = min(0, elem.vy + self.af * abs(elem.vx))
            elem.vx = self.phy_for(self.vx, elem.vx, self.m, elem.m, coef)
        elif direction == 2 or direction == 4:
            if elem.vx > 0:
                elem.vx = max(0, elem.vx - self.af * abs(elem.vy))
            else:
                elem.vx = min(0, elem.vx + self.af * abs(elem.vy))
            elem.vy = self.phy_for(self.vy, elem.vy, self.m, elem.m, coef)
        else:
            return
        """
        elem.vx = elem.vy = 0"""

    def sim(self, time):
        """
        simulate the element move in the certain direction for certain time.
        REMEMBER TO CHECK!
        """
        self.vy += self.mylevel.g * time
        x1 = self.x + time * self.vx
        y1 = self.y + time * self.vy
        self.update(x1, y1)

    def within_screen(self, scr_left, scr_right, scr_top, scr_bot):
        """
        return True if the element is in screen; False otherwise.
        scr_left: the left bound of the screen
        scr_right: the right bound of the screen
        """
        #TODO:  Fixme
        return True

    def draw(self, screen, x, y, w, h):
        """
        convey the arguments x and y to graphics function to draw things.
        """
        self.graphics.draw(screen, x, y, w, h)
Beispiel #2
0
    def update():
        FPS._current_frames += 1

        FPS._previous_time = FPS._current_time
        FPS._current_time = time.time()

        FPS._delta_time = FPS._current_time - FPS._previous_time
        FPS._last_update += FPS._delta_time

        if FPS._last_update >= 1:
            FPS._current_fps = FPS._current_frames

            FPS._current_frames = 0
            FPS._last_update = 0

            FPS._surface = FPS._font.render("FPS: " + str(FPS._current_fps), 1, System.Color.WHITE)
            FPS._outline_surface = \
                FPS._font.render("FPS: " + str(FPS._current_fps), 1, System.Color.BLACK)

            FPS._surface_rect = FPS._surface.get_rect()
            FPS._surface_rect.move_ip(Graphics.get_resolution()[0] / 2, 15)

            FPS._outline_surface_rect = FPS._surface.get_rect()

        # Draws an outline for the FPS 
        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x + 1, FPS._surface_rect.y,
                                  FPS._surface_rect.width, FPS._surface_rect.height))
        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x - 1, FPS._surface_rect.y,
                                  FPS._surface_rect.width, FPS._surface_rect.height))
        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x, FPS._surface_rect.y + 1,
                                  FPS._surface_rect.width, FPS._surface_rect.height))
        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x, FPS._surface_rect.y - 1,
                                  FPS._surface_rect.width, FPS._surface_rect.height))

        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x + 1, FPS._surface_rect.y + 1,
                                  FPS._surface_rect.width, FPS._surface_rect.height))
        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x - 1, FPS._surface_rect.y - 1,
                                  FPS._surface_rect.width, FPS._surface_rect.height))
        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x - 1, FPS._surface_rect.y + 1,
                                  FPS._surface_rect.width, FPS._surface_rect.height))
        Graphics.draw(FPS._outline_surface,
                      pygame.Rect(FPS._surface_rect.x + 1, FPS._surface_rect.y - 1,
                                  FPS._surface_rect.width, FPS._surface_rect.height))
        # End of Outline

        Graphics.draw(FPS._surface, FPS._surface_rect)

        FPS._clock.tick(System.Display.TARGET_FPS)
Beispiel #3
0
    def draw(self):
        if self._nodes_surface_dirty or self._font_surface_dirty or self._debug_surface_dirty:

            if self._nodes_surface_dirty:
                self._nodes_surface.fill(System.Color.TRANSPARENT)
            if self._font_surface_dirty:
                self._font_surface.fill(System.Color.TRANSPARENT)
            if self._debug_surface_dirty:
                self._debug_surface.fill(System.Color.TRANSPARENT)

            for x in range(0, len(self._search_space.nodes)):
                for y in range(0, len(self._search_space.nodes[x])):

                    if self._nodes_surface_dirty:
                        node_surface = pygame.Surface(
                            (System.Graph.NODE_WIDTH, System.Graph.NODE_HEIGHT))

                        self._search_space.nodes[x][y].update_surface_color(
                            self._search_space.open_list, self._search_space.closed_list,
                            self._search_space.start_node, self._search_space.end_node)
                        node_surface.fill(self._search_space.nodes[x][y].surface_color)

                        self._nodes_surface.blit(
                            node_surface, self._search_space.nodes[x][y].surface_rect)

                    if self._debug_surface_dirty \
                            and self._search_space.nodes[x][y].parent_node is not None:
                        pygame.draw.line(
                            self._debug_surface,
                            System.Color.BLACK,
                            (self._search_space.nodes[x][y].surface_rect.x +
                             (self._search_space.nodes[x][y].surface_rect.width / 2),
                             self._search_space.nodes[x][y].surface_rect.y +
                             (self._search_space.nodes[x][y].surface_rect.height / 2)),
                            (self._search_space.nodes[x][y].parent_node.surface_rect.x +
                             (self._search_space.nodes[x][y].parent_node.surface_rect.width / 2),
                             self._search_space.nodes[x][y].parent_node.surface_rect.y +
                             (self._search_space.nodes[x][y].parent_node.surface_rect.height / 2)
                            ))

                    if self._font_surface_dirty and self._search_space.nodes[x][y].traversable:
                        text_color = \
                            System.Color.BLACK \
                            if self._search_space.nodes[x][y] in self._search_space.open_list \
                            else System.Color.LIGHT_GREY

                        h_text_surface = self._font.render(
                            'H: ' + str(self._search_space.nodes[x][y].h_score), 1, text_color)

                        h_text_surface_rect = h_text_surface.get_rect()
                        h_text_surface_rect = (
                            self._search_space.nodes[x][y].surface_rect.x +
                            self._search_space.nodes[x][y].surface_rect.width -
                            h_text_surface_rect.width,
                            self._search_space.nodes[x][y].surface_rect.y +
                            self._search_space.nodes[x][y].surface_rect.height -
                            h_text_surface_rect.height)

                        g_text_surface = self._font.render(
                            'G: ' + str(self._search_space.nodes[x][y].g_score), 1, text_color)

                        g_text_surface_rect = h_text_surface.get_rect()
                        g_text_surface_rect = (
                            self._search_space.nodes[x][y].surface_rect.x,
                            self._search_space.nodes[x][y].surface_rect.y +
                            self._search_space.nodes[x][y].surface_rect.height -
                            g_text_surface_rect.height)

                        f_text_surface = self._font.render(
                            'F: ' + str(self._search_space.nodes[x][y].f_score), 1, text_color)

                        f_text_surface_rect = self._search_space.nodes[x][y].surface_rect

                        self._font_surface.blit(h_text_surface, h_text_surface_rect)
                        self._font_surface.blit(g_text_surface, g_text_surface_rect)
                        self._font_surface.blit(f_text_surface, f_text_surface_rect)

            if self._nodes_surface_dirty and not self._display_help:
                direction_list = [(1, 0), (0, 1), (-1, 0), (0, -1),
                                  (1, 1), (-1, -1), (1, -1), (-1, 1), (0, 0)]

                i = 0
                for direction in direction_list:
                    temp_text = self._help_font.render(
                        'F1 = Help', 1,
                        System.Color.WHITE if i == len(direction_list) - 1 else System.Color.BLACK)
                    temp_text_rect = temp_text.get_rect()

                    temp_text_rect.x += direction[0]
                    temp_text_rect.y += direction[1]
                    self._nodes_surface.blit(temp_text, temp_text_rect)

                    i += 1

            if self._debug_surface_dirty:
                current_path_node = self._search_space.end_node
                while current_path_node.parent_node is not None:
                    pygame.draw.line(
                        self._debug_surface,
                        System.Color.DARK_GREEN,
                        (
                            current_path_node.surface_rect.x +
                            (current_path_node.surface_rect.width / 2),
                            current_path_node.surface_rect.y +
                            (current_path_node.surface_rect.height / 2)),
                        (
                            current_path_node.parent_node.surface_rect.x +
                            (current_path_node.parent_node.surface_rect.width / 2),
                            current_path_node.parent_node.surface_rect.y +
                            (current_path_node.parent_node.surface_rect.height / 2)),
                        5)

                    current_path_node = current_path_node.parent_node

            self._nodes_surface_dirty = False
            self._font_surface_dirty = False
            self._debug_surface_dirty = False

        Graphics.draw(self._nodes_surface, self._nodes_surface_rect)

        if self._display_debug:
            Graphics.draw(self._debug_surface, self._debug_surface_rect)

        if self._display_text:
            Graphics.draw(self._font_surface, self._font_surface_rect)

        if self._display_help:
            Graphics.draw(self._help_surface, self._help_surface_rect)

        if self._paused:
            Graphics.draw(self._pause_surface, self._pause_surface_rect)
Beispiel #4
0
class GameEngine:
    def __init__(self):
        self.is_running = False
        self.is_alive = False
        self.is_train = False
        self.is_human = True

        self.__hero = Hero()

        self.__score = 0
        self.__action_queue = []

        self.__width = WIDTH
        self.__height = HEIGHT

        self.__clock = None
        self.__environment = None

        self.screen = pg.display.set_mode((self.__width, self.__height))

        pg.init()

        self.__graphics = Graphics(self.screen)
        self.menu = GameMenu(self, self.screen)

    @staticmethod
    def off_screen():
        pg.display.iconify()

    def setup(self):
        self.is_running = True
        self.is_alive = True

        self.__action_queue = []
        self.__score = 0

        self.__hero = Hero()
        self.__environment = Environment()

        self.__environment.create_level()
        self.__clock = pg.time.Clock()

    def __key_checker(self, event):
        if not self.is_train:
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    self.menu.pause_menu()

                elif event.key == pg.K_SPACE:
                    if not self.is_alive:
                        self.menu.start_menu()

                    elif 'jump' not in self.__action_queue:
                        self.__action_queue.append('jump')

                elif event.key == pg.K_LCTRL:
                    if 'sit' not in self.__action_queue:
                        self.__action_queue.append('sit')

            elif event.type == pg.KEYUP:
                if event.key == pg.K_SPACE:
                    if 'jump' in self.__action_queue:
                        self.__action_queue.remove('jump')

                elif event.key == pg.K_LCTRL:
                    if 'sit' in self.__action_queue:
                        self.__action_queue.remove('sit')

    def get_action_from_key_check(self):
        if len(self.__action_queue) == 0:
            return 'nothing'
        else:
            return self.__action_queue[0]

    def __collision_check(self):
        collision_logic = CollisionLogic()
        current_prop = self.__environment.prop_list[0]

        if collision_logic.check_collision(self.__hero, current_prop):
            self.is_alive = False

    def get_state(self):
        cur_prop = self.__environment.prop_list[0]

        hero_y = self.__hero.coord[1]
        hero_x_size, hero_y_size = self.__hero.size
        hero_r_u_x = hero_x_size
        hero_r_u_y = hero_y + hero_y_size
        hero_vel_y = self.__hero.vel[1]
        hero_acc_y = self.__hero.acc[1]

        prop_x, prop_y = cur_prop.coord
        prop_x_size, prop_y_size = cur_prop.size
        prop_r_u_x = prop_x + prop_x_size
        prop_r_u_y = prop_y + prop_y_size
        prop_vel_x = cur_prop.vel[0]

        hero_y /= self.__height
        hero_r_u_x /= self.__width
        hero_r_u_y /= self.__height
        hero_vel_y /= MAX_VEL
        hero_acc_y /= MAX_ACC

        prop_x /= self.__width
        prop_y /= self.__height
        prop_r_u_x /= self.__width
        prop_r_u_y /= self.__height
        prop_vel_x /= MAX_VEL

        result = [
            hero_y, hero_r_u_x, hero_r_u_y, hero_vel_y, hero_acc_y, prop_x,
            prop_y, prop_r_u_x, prop_r_u_y, prop_vel_x
        ]
        return result

    def get_all_info(self):
        next_state = self.get_state()
        reward = 1
        done = not self.is_alive

        return next_state, reward, done

    def render(self):
        self.__clock.tick(FPS)

        for event in pg.event.get():
            if event.type == pg.QUIT:
                exit(0)
            else:
                self.__key_checker(event)

        if not self.is_alive:
            finished = self.__graphics.draw_wasted_screen()
            if finished:
                self.menu.start_menu()
        else:
            visible_obj = self.__environment.prop_list
            self.__graphics.draw(self.__hero, visible_obj, self.__score,
                                 STANDARD_MODE)

        pg.display.update()

    def step(self, action):
        self.__score += 1

        self.__collision_check()

        self.__hero.change_state(action)
        self.__hero.update()
        self.__environment.update()
Beispiel #5
0
class Element(object):
    exist = True
    def __init__(self, x_co, y_co, w_co, h_co, vx_co, vy_co, mass, level_co, c_co):
        """
        initialize everything
        x_co, y_co: the center coordinates.
        w_co, h_co: the width and height.
        vx_co, vy_co: speed to 2 coordinates.
        c_co: coefficient of restitution
        """
        self.w = w_co
        self.h = h_co
        self.vx = vx_co
        self.vy = vy_co
        self.mylevel = level_co
        self.graphics = Graphics(self)
        self.m = mass
        self.c = c_co
        self.update(x_co, y_co)
        self.af = 0.9

    def set_exist(self, x):
        self.exist = x

    def update(self, x1, y1):
        """
        update the position of element
        """
        self.x = x1
        self.y = y1
        self.left = self.x - self.w/2.0
        self.right = self.x + self.w/2.0
        self.top = self.y - self.h/2.0
        self.bottom = self.y + self.h/2.0
        
        
    def in_inter(self, x, a, b):
        """
        return true when x is inside the interval [a, b]
        """
        assert a <= b, 'Invalid interval'
        if x >= a and x <= b:
            return True
        return False


    def touch(self, elem):
        """
        return true if the two elements are overlapped by the other
        """
        gapright =  self.right - elem.left
        gapleft =   elem.right - self.left
        gaptop =    -self.top + elem.bottom
        gapbottom = -elem.top + self.bottom
        if gapleft > 0 and gapright > 0 and gaptop > 0 and gapbottom > 0:
            if min(gapleft, gapright) < min(gaptop, gapbottom):
                #collision horizontal
                if gapleft < gapright:
                    return 3
                else:
                    return 1
            else:
                #collision vertical
                if gaptop < gapbottom:
                    return 2
                else:
                    return 4
        else:
            return 0
    
    def touch_ammount(self, elem):
        gapright =  self.right - elem.left
        gapleft =   elem.right - self.left
        gaptop =    -self.top + elem.bottom
        gapbottom = -elem.top + self.bottom
        direction =  self.touch(elem)
        if direction == 0:
            return 0
        elif direction == 1:
            return gapright
        elif direction == 2:
            return gaptop
        elif direction == 3:
            return gapleft
        elif direction == 4:
            return gapbottom
        else:
            assert False, "invalid direction"

    def move(self, elem):
        """
          move something out of another element under the presumption that those two elements are overlapped
          return nothing
        """
        direction = self.touch(elem)
        ammount = self.touch_ammount(elem)
        if direction == 0:
            return
        elif direction == 1:
            elem.x += ammount
        elif direction == 2:
            elem.y -= ammount
        elif direction == 3:
            elem.x -= ammount
        elif direction == 4:
            elem.y += ammount
        else:
            assert False, "invalid direction"

        elem.update(elem.x, elem.y)
            

    def phy_for(self, va, vb, ma, mb, coef):
        """
        take in objects a and b's speed and mass and return the speed for object b
        coef is the coefficient of restitution which is the average of the c of two elements
        """
        v = (coef * ma * (va - vb) + ma * va + mb * vb) / (ma + mb)
        return v
        


    def collide(self, elem):
        """
        modify the other element's speed; return nothing
        """
        direction = self.touch(elem)
        coef = (self.c + elem.c)/2
        if direction == 1 or direction == 3:
            if elem.vy > 0:
                elem.vy = max(0, elem.vy - self.af * abs(elem.vx))
            else:
                elem.vy = min(0, elem.vy + self.af * abs(elem.vx))
            elem.vx = self.phy_for(self.vx, elem.vx, self.m, elem.m, coef)
        elif direction == 2 or direction == 4:
            if elem.vx > 0:
                elem.vx = max(0, elem.vx - self.af * abs(elem.vy))
            else:
                elem.vx = min(0, elem.vx + self.af * abs(elem.vy))
            elem.vy = self.phy_for(self.vy, elem.vy, self.m, elem.m, coef)
        else:
            return
        """
        elem.vx = elem.vy = 0"""

    def sim(self, time):
        """
        simulate the element move in the certain direction for certain time.
        REMEMBER TO CHECK!
        """
        self.vy += self.mylevel.g * time
        x1 = self.x + time * self.vx
        y1 = self.y + time * self.vy
        self.update(x1, y1)
        
        

    def within_screen(self, scr_left, scr_right, scr_top, scr_bot):
        """
        return True if the element is in screen; False otherwise.
        scr_left: the left bound of the screen
        scr_right: the right bound of the screen
        """
#TODO:  Fixme
        return True
    

    def draw(self, screen, x, y, w, h):
        """
        convey the arguments x and y to graphics function to draw things.
        """
        self.graphics.draw(screen, x, y, w, h)
Beispiel #6
0
class Game:
	"""A class for starting a game of Minesweeper."""
	SAVES_PATH = "./Saves/"
	SAVE_FILE = SAVES_PATH + "minefield.save"
	
	def __init__(self, screen):
		"""
		Constructs an instance of Game and returns it.
		
		screen: a standard screen object from the curses library.
		"""
		# Create a Graphics class to handle drawing.
		self.graphics = Graphics(screen)
		
		# The last valid input by the user.
		self.last_valid_command = ""
		
		# Controls the game loop.
		self.running = True
		
		# Current scene.
		self.scene = None
	
	def start(self):
		"""Starts the game loop at the menu scene."""
		self.change_scene(sm.mk_MenuScene(self))
		self.loop()
	
	def loop(self):
		"""Main game loop."""
		while self.running:
			self.scene.loop()
	
	def change_scene(self, scene, command=""):
		"""Sets the next scene."""
		self.scene = scene
		if command == "":
			command = scene.first_command
		self.last_valid_command = command
	
	def stop(self):
		"""Stops the game loop."""
		self.running = False
	
	def get_input(self, message="", show_default=True, repeat=chr(10)):
		"""
		Gets a one-character input from the user and returns it. A
		message and a default response are also drawn to the screen.The
		default response is returned if the user inputs the enter key.
		
		message: a string displayed before requesting user input.
		show_default: shows the default response if True.
		return: a character input.
		"""
		x = 0
		y = self.graphics.HEIGHT-1
		if show_default:
			input = "{} ({})".format(message, self.last_valid_command)
		else:
			input = message
		self.graphics.draw(x, y, input)
		
		key = self.graphics.get_input()
		if key == repeat:
			return self.last_valid_command
		return key