예제 #1
0
class Application:
    def __init__(self, title, _width, _height):
        pygame.init()
        self.surface = pygame.display.set_mode((_width, _height))
        pygame.display.set_caption(title)

        self.clock = pygame.time.Clock()
        self.fps = 60

        self.running = True
        self.resolution = 2

        self.Scenes = Scene(self.surface, _width, _height)

    def Run(self):
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

            keys = pygame.key.get_pressed()
            if len(keys):
                self.Scenes.key_pressed(keys)

            self.surface.fill((10, 10, 10))
            self.Scenes.draw()
            #print("tick {0} | fps {1}".format(self.clock.tick(self.fps), self.clock.get_fps()))

            pygame.display.update()
        pygame.quit()
예제 #2
0
 def draw(self, screen):
     s = pygame.Surface((SCREEN_W, SCREEN_H))
     self.pausedScene.draw(s)
     self.bluredBackground = self.blur(s, self.b)
     if self.b < 10:
         self.b = self.b + 0.1
     screen.blit(self.bluredBackground, (0, 0))
     Scene.draw(self, screen)
예제 #3
0
 def draw(self, screen):
     s = pygame.Surface((SCREEN_W, SCREEN_H))
     self.pausedScene.draw(s)
     self.bluredBackground = self.blur(s, self.b)
     if self.b < 10:
         self.b = self.b + 0.1
     screen.blit(self.bluredBackground, (0, 0))
     Scene.draw(self, screen)
예제 #4
0
파일: Level.py 프로젝트: dgalaktionov/Aleph
    def draw(self, screen):
        screen.fill(0x000000)

        if self.bg:
            screen.blit(self.bg, self.camera.state)

        if Constants.DEBUG:
            self.drawRaytracing(screen)
        self.player.draw(screen, self.camera)
        for group in self.groups:
            group.draw(screen, self.camera)
        self.drawDanger(screen);
        
        # TODO: move maps and characters to its own layer
        Scene.draw(self, screen)  # draws rest of layers
예제 #5
0
파일: Level.py 프로젝트: hmourit/Aleph
    def draw(self, screen):
        screen.fill(0x000000)

        if self.bg:
            screen.blit(self.bg, self.camera.state)

        if Constants.DEBUG:
            self.drawRaytracing(screen)
        self.player.draw(screen, self.camera)
        for group in self.groups:
            group.draw(screen, self.camera)
        self.drawDanger(screen)

        # TODO: move maps and characters to its own layer
        Scene.draw(self, screen)  # draws rest of layers
예제 #6
0
class Screen:
    window = None
    lastFrame = 0
    clock = None
    scene = None
    framesCount = 0

    def __init__(self, sizeX, sizeY):
        pygame.init()
        self.window = pygame.display.set_mode((sizeX, sizeY))
        self.clock = pygame.time.Clock()
        self.scene = Scene()

    def update(self):
        self.lastFrame += self.clock.tick()
        if self.lastFrame >= 15:
            self.framesCount += 1
            self.scene.draw(self.window, self.framesCount)
            self.scene.serveFood()
            if self.framesCount == 5:
                self.framesCount = 0
            self.lastFrame = 0
            pygame.display.update()

    def getKeyInput(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            if self.scene.snake.moveDirection != "RIGHT":
                self.scene.snake.moveDirection = "LEFT"
        elif keys[pygame.K_RIGHT]:
            if self.scene.snake.moveDirection != "LEFT":
                self.scene.snake.moveDirection = "RIGHT"
        elif keys[pygame.K_UP]:
            if self.scene.snake.moveDirection != "DOWN":
                self.scene.snake.moveDirection = "UP"
        elif keys[pygame.K_DOWN]:
            if self.scene.snake.moveDirection != "UP":
                self.scene.snake.moveDirection = "DOWN"
예제 #7
0
파일: Game7.py 프로젝트: Guaderxx/Games
def main():
	# 初始化
	pygame.init()
	screen = pygame.display.set_mode((WIDTH, HEIGHT))
	pygame.display.set_caption("T-Rex Rush-公众号: Charles的皮卡丘")
	clock = pygame.time.Clock()
	# 得分
	score = 0
	# 加载一些素材
	jump_sound = pygame.mixer.Sound("./music/jump.wav")
	jump_sound.set_volume(6)
	die_sound = pygame.mixer.Sound("./music/die.wav")
	die_sound.set_volume(6)
	pygame.mixer.init()
	pygame.mixer.music.load("./music/bg_music.mp3")
	pygame.mixer.music.set_volume(0.6)
	pygame.mixer.music.play(-1)
	font = pygame.font.Font('./font/simkai.ttf', 20)
	# 实例化
	dinosaur = Dinosaur(WIDTH, HEIGHT)
	scene = Scene(WIDTH, HEIGHT)
	plants = pygame.sprite.Group()
	pteras = pygame.sprite.Group()
	# 产生障碍物事件
	GenPlantEvent = pygame.constants.USEREVENT + 0
	pygame.time.set_timer(GenPlantEvent, 1500)
	GenPteraEvent = pygame.constants.USEREVENT + 1
	pygame.time.set_timer(GenPteraEvent, 5000)
	# 游戏是否结束了
	running = True
	# 是否可以产生障碍物flag
	flag_plant = False
	flag_ptera = False
	t0 = time.time()
	# 主循环
	while running:
		for event in pygame.event.get():
			if event.type == QUIT:
				sys.exit()
				pygame.quit()
			if event.type == GenPlantEvent:
				flag_plant = True
			if event.type == GenPteraEvent:
				if score > 50:
					flag_ptera = True
		key_pressed = pygame.key.get_pressed()
		if key_pressed[pygame.K_SPACE]:
			dinosaur.is_jumping = True
			jump_sound.play()
		screen.fill(BACKGROUND)
		time_passed = time.time() - t0
		t0 = time.time()
		# 场景
		scene.move()
		scene.draw(screen)
		# 小恐龙
		dinosaur.is_running = True
		if dinosaur.is_jumping:
			dinosaur.be_afraid()
			dinosaur.jump(time_passed)
		dinosaur.draw(screen)
		# 障碍物-植物
		if random.random() < sigmoid(score) and flag_plant:
			plant = Plant(WIDTH, HEIGHT)
			plants.add(plant)
			flag_plant = False
		for plant in plants:
			plant.move()
			if dinosaur.rect.left > plant.rect.right and not plant.added_score:
				score += 1
				plant.added_score = True
			if plant.rect.right < 0:
				plants.remove(plant)
				continue
			plant.draw(screen)
		# 障碍物-飞龙
		if random.random() < sigmoid(score) and flag_ptera:
			if len(pteras) > 1:
				continue
			ptera = Ptera(WIDTH, HEIGHT)
			pteras.add(ptera)
			flag_ptera = False
		for ptera in pteras:
			ptera.move()
			if dinosaur.rect.left > ptera.rect.right and not ptera.added_score:
				score += 5
				ptera.added_score = True
			if ptera.rect.right < 0:
				pteras.remove(ptera)
				continue
			ptera.draw(screen)
		# 碰撞检测
		if pygame.sprite.spritecollide(dinosaur, plants, False) or pygame.sprite.spritecollide(dinosaur, pteras, False):
			die_sound.play()
			running = False
		# 显示得分
		score_text = font.render("Score: "+str(score), 1, (0, 0, 0))
		screen.blit(score_text, [10, 10])
		pygame.display.flip()
		clock.tick(60)
	res = show_gameover(screen)
	return res
예제 #8
0
class HaxballEnvironment :
    def __init__(self, random_start = True, step_limit = None, ball_idle_limit = None, state_output_mode = 'pixels', rendering = True, frame_skip=4):
        self.action_space = ActionSpace([Action.up, Action.down, Action.forward, Action.backward, Action.nomoveshoot, Action.nomove])
        self.step_limit = step_limit
        self.ball_idle_limit = ball_idle_limit
        self.state_output_mode = state_output_mode
        self.rendering = rendering
        self.ball_idle = 0
        self.step_limit = step_limit
        if state_output_mode == 'pixels': self.rendering = True
        self.step_count = 0
        self.random_start = random_start
        self.frame_skip = frame_skip
    
    
        self.scene =  Scene(c_width, c_height)
        self.scene.add_object(Box(5, c_width - 5, 5, c_height - 5, 0))
        self.scene.add_object(Disc(c_width / 2, c_height / 2, middle_field_radius, 10, 1, 1, Color.white).make_ghost().make_hollow().set_outer_color(Color.border))
        self.scene.add_object(VerticalBorder(c_width / 2, c_height / 2, c_height - 2 * topbottom_margin, None).make_ghost())


        self.scene.add_object(HorizontalBorder(c_width / 2, topbottom_margin, c_width - 2 * leftright_margin, border_restitution).extend_to(Way.up).set_collision_mask([Ball]))
        self.scene.add_object(HorizontalBorder(c_width / 2, c_height - topbottom_margin, c_width - 2 * leftright_margin, border_restitution).extend_to(Way.down).set_collision_mask([Ball]))
        self.scene.add_object(VerticalBorder(leftright_margin, (c_height / 2 - goal_length / 2 + topbottom_margin) / 2, c_height / 2 - topbottom_margin - goal_length / 2, border_restitution).extend_to(Way.left).set_collision_mask([Ball]))
        self.scene.add_object(VerticalBorder(leftright_margin, c_height - (c_height / 2 - goal_length / 2 + topbottom_margin) / 2, c_height / 2 - topbottom_margin - goal_length / 2, border_restitution).extend_to(Way.left).set_collision_mask([Ball]))
        self.scene.add_object(VerticalBorder(c_width - leftright_margin, (c_height / 2 - goal_length / 2 + topbottom_margin) / 2, c_height / 2 - topbottom_margin - goal_length / 2, border_restitution).extend_to(Way.right).set_collision_mask([Ball]))
        self.scene.add_object(VerticalBorder(c_width - leftright_margin, c_height - (c_height / 2 - goal_length / 2 + topbottom_margin) / 2, c_height / 2 - topbottom_margin - goal_length / 2, border_restitution).extend_to(Way.right).set_collision_mask([Ball]))
        
       
        self.goal1 = Goal(leftright_margin, c_height / 2, Way.left, goal_length)
        self.goal2 = Goal(c_width - leftright_margin, c_height / 2, Way.right, goal_length)
        
        self.player1 = Player(120, c_height / 2, player_radius, player_mass, \
                                     player_restitution, player_damping, player_kick_damping, player_kick_power, Side.red)
       
        self.player2 = Player(c_width - 120, c_height / 2, player_radius, player_mass, \
                                     player_restitution, player_damping, player_kick_damping, player_kick_power, Side.blue)
       
        self.ball = Ball(c_width / 2, c_height / 2, ball_radius, ball_mass, ball_restitution, ball_damping)
        
        self.scene.add_object(self.goal1)
        self.scene.add_object(self.goal2)
        self.scene.add_object(self.player1)
        self.scene.add_object(self.player2)
        self.scene.add_object(self.ball)
        
        
        self.sequence1 = StateSequence([84, 84, 4])
        self.sequence2 = StateSequence([84, 84, 4])
        
        
    def step(self, action_red, action_blue = -1):
        #ai action no frameskip
        if self.player2.center.x > self.ball.center.x:
            if random.random() < 0.02:
                self.player2.apply_action(Action.nomoveshoot)
            else:
                self.player2.apply_action(Action.nomove)
                
        #agent action
        for n in range(self.frame_skip):
            self.player2.apply_force(self.ai_select_force())
            self.player1.apply_action(self.action_space[action_red])
            self.scene.update()
            self.step_count += 1

        if self.rendering == True:
            self.render()
            
        if self.ball.velocity.magnitude() < 0.1:
            self.ball_idle += 1
        else:
            self.ball_idle = 0

        
        return self._get_state_reward_done_info()
    
    def ai_select_force(self):
        ai_agent_pos = self.player2.center
        ball_pos = self.ball.center
        goal_pos = self.goal1.center
        unit_goal_to_ball = Vector.sub(ball_pos, goal_pos).normalize()
        
        attract_point = ball_pos.add(unit_goal_to_ball.mult(self.ball.radius))
        repel_point = ball_pos.sub(unit_goal_to_ball.mult(self.ball.radius))
        
        attract_force = Vector.sub(attract_point, ai_agent_pos)
        repel_force   = Vector.sub(ai_agent_pos, repel_point).mult(0.2)
        unit_total_force = Vector.add(attract_force, repel_force).normalize()
        
        return unit_total_force
        
        
    
    def render(self):
        self.scene.draw()
        
    def reset(self):
        self.scene.reset()
        self.ball_idle = 0
        self.episode_end = False
        if (self.random_start) :
            self.scene.meta_objects['balls'][0].apply_impulse(Vector(random.random() - 0.5, random.random() - 0.5).mult(20))
        self.step_count = 0
        self.render()
        
        return self._calculate_state()

    def _get_state_reward_done_info(self):
        state = self._calculate_state()
        reward = self._calculate_reward()
        
        done = self._calculate_done()
        
        info = self._calculate_info()
        
        return [state, reward, done, info]
    
    
    def _calculate_reward(self):
        v_player = self.player1.velocity
        v_ball   = self.ball.velocity
        
        player_to_ball_vec = Vector.sub(self.ball.center, self.player1.center)
        
        if Vector.dot(Vector.sub(v_player, v_ball), player_to_ball_vec) > 0:
            player_to_ball = 1
        else:
            player_to_ball = 0
            
        ball_to_goal_vec = Vector.sub(self.goal2.center, self.ball.center)
            
        if Vector.dot(v_ball, ball_to_goal_vec) > 0:
            ball_to_goal = 1
        else:
            ball_to_goal = 0
            
        goal = self._calculate_info()['goal']
        reward = goal
        
        return reward
    
    def _calculate_done(self):
        if self.step_limit == None or self.step_count < self.step_limit :
            step_limit_reached = False
        else:
            step_limit_reached = True
        
        if self.ball_idle_limit == None or self.ball_idle < self.ball_idle_limit:
            ball_idle_limit_reached = False
        else:
            ball_idle_limit_reached = True
        
        
        return self.scene.check_goals() or step_limit_reached or ball_idle_limit_reached 
        
    def _calculate_state(self):
        if self.state_output_mode == 'locations':    
            p1x = self.player1.center.x
            p1y = self.player1.center.y
            bx = self.ball.center.x
            by = self.ball.center.y
            p2x = self.player2.center.x
            p2y = self.player2.center.y
            
            horiz = c_width / 2
            vert = c_height / 2
            
            p1x = (p1x - horiz) / horiz
            p1y = (p1y - vert) / vert
            p2x = (p2x - horiz) / horiz
            p2y = (p2y - vert) / vert
            bx = (bx - horiz) / horiz
            by = (by - vert) / vert
            
            state_for_p1 = np.array([p1x, p1y, p2x, p2y, bx, by])
            state_for_p2 = np.array([-p2x, p2y, -p1x, p1y, -bx, by])
            return [state_for_p1, state_for_p2]
        
        
        elif self.state_output_mode == 'pixels':    
            obs_size = (400, 600) 
            pad_size = obs_size[0] // 2, obs_size[1] // 2
            obs = self.scene.get_scene_as_array()
            
#            obs = np.pad(obs[:,:,1], ((pad_size[0],), (pad_size[1],)) , 'edge')
            
            p1x = int(self.player1.center.x + pad_size[1]) 
            p1y = int(self.player1.center.y + pad_size[0])
#            p2x = int(self.player2.center.x + pad_size[1]) 
#            p2y = int(self.player2.center.y + pad_size[0])
#            obs1 = obs[p1y - obs_size[0] // 2: p1y + obs_size[0] // 2, p1x - obs_size[1] // 2: p1x + obs_size[1] // 2]
#            obs2 = obs[p2y - obs_size[0] // 2: p2y + obs_size[0] // 2, p2x - obs_size[1] // 2: p2x + obs_size[1] // 2]
            obs1 = obs[:,:,0]
            obs1 = imresize(obs1, (84, 84))
#            obs2 = imresize(obs2, (84, 84))
            self.sequence1.append_obs(obs1)
#            self.sequence2.append_obs(obs2[:,::-1])
            return self.sequence1.get_sequence()#, self.sequence1.get_sequence()
        else:
            raise Exception('invalid state output mode: {}'.format(self.state_output_mode))
        
        
    
    def _calculate_info(self):
        info = {
            "goal": 0,
            "ball_at_side": 0,
            "closer_player_to_ball": -1
        }
        
        
        if self.ball.center.x > c_width / 2:
            info['ball_at_side'] = 1
        elif self.ball.center.x < c_width / 2:
            info['ball_at_side'] = -1
        else:
            info['ball_at_side'] = 0
        
        if self.scene.check_goals():
            if info['ball_at_side'] == 1:
                info['goal'] = 1
            elif info['ball_at_side'] == -1:
                info['goal'] = -1
        
        if Vector.dist(self.player1.center, self.ball.center) < Vector.dist(self.player2.center, self.ball.center):
            info["closer_player_to_ball"] = 0
        else:
            info["closer_player_to_ball"] = 1
        return info
        
        
    def close(self):
        pass
예제 #9
0
class PenaltyEnvironment:
    def __init__(self, frame_skip = 2):
        
        height = 400
        width = 600
        goal_length = 300
        self.scene =  Scene(width, height)
        self.frame_skip = frame_skip
        self.ball_idle = 0
        self.ball_idle_limit = 3

        self.action_space = ActionSpace([Action.up, Action.down, Action.nomoveshoot])
       
        self.box = Box(0, width, 0, height, 0)
        self.goal1 = Goal(leftright_margin, height / 2, Way.left, goal_length)

        self.player1 = Player(80, height / 2, player_radius, player_mass, \
                                     player_restitution, player_damping, player_kick_damping, player_kick_power, Side.red)
       
       
        self.ball = Ball(width - 100, height / 2, ball_radius, ball_mass, ball_restitution, ball_damping)
        self.penalty_spot = Disc(self.ball.center.x, self.ball.center.y, 4, 0, 0, 0, Color.green).make_ghost().make_hollow()
#        self.player_border_left = VerticalBorder(50, height / 2, height, 0, visible=True)
#        self.player_border_right = VerticalBorder(100, height / 2, height, 0, visible=True)
        
        self.scene.add_object(self.goal1)
        self.scene.add_object(self.player1)
        self.scene.add_object(self.ball)
        self.scene.add_object(self.penalty_spot)
        self.scene.add_object(self.box)
        self.reset()

#        self.scene.add_object(self.player_border_left)
#        self.scene.add_object(self.player_border_right)

    def step(self, action=1):
        for n in range(self.frame_skip):
            self.player1.apply_action(self.action_space[action])
            self.scene.update()
        
        if self.ball.velocity.magnitude() < 0.5:
            self.ball_idle += 1
            
        return self._get_state_reward_done_info()

    def reset(self):
        self.scene.reset()
        self.ball.apply_impulse(Vector(-25, random.random() * 16 - 8))
        self.ball_idle = 0
        
        
    def render(self):
        self.scene.draw()
        
    
    def _get_state_reward_done_info(self):
        state = self._calculate_state()
        reward = self._calculate_reward()
        
        done = self._calculate_done()
        
        info = self._calculate_info()
        
        return [state, reward, done, info]
    
    
    def _calculate_state(self):
        self.scene.draw()
        obs = self.scene.get_scene_as_array()
        return imresize(obs, [210,160])
        
    
    def _calculate_reward(self):
        if self.scene.check_goals():
            return -1
        elif self.ball_idle > self.ball_idle_limit:
            return 1
        else:
            return 0
    
        
    def _calculate_done(self):
            return self.scene.check_goals() or self.ball_idle > self.ball_idle_limit
        
    
    def _calculate_info(self):
        return {}
예제 #10
0
class GameEngine(object):
    """
    The Fortune Engine GameEngine is a main loop wrapper around pygame.
    It manages the event and drawing loops allowing the user to just
    register for user events and drawing time in the draw loop.
    """
    instance = None

    def __init__(self,
                 width=1200,
                 height=900,
                 always_draw=False,
                 fps_cap=15,
                 version=False,
                 title="FortuneEngine"):
        """
        Constructor for the game engine.

        @param width:        Window width
        @param height:       Window height
        @param always_draw:  Boolean to set the animation mode to always
                             draw vs draw when set_dirty is called
        @param fps_cap:      Sets the framerate cap. Set to 0 to disable
                             the cap. Warning: setting the cap to 0 when
                             always draw = False will cause cpu 100% when
                             not driving.
        @param version:      If true, use new rendering system, false uses
                             only the draw system
        @param title:        Window Title
        """
        GameEngine.instance = self
        pygame.init()
        pygame.mouse.set_visible(False)
        self.__version = version  #true is new, false is old

        # Window Settings
        self.width = width
        self.height = height
        size = width, height
        self.screen = pygame.display.set_mode(size)
        pygame.display.set_caption(title)
        self.__fps = DrawableFontObject("", pygame.font.Font(None, 17))
        self.__fps.setPosition(0, 0)
        self.__scene = Scene(self.__fps)

        # Engine Internal Variables
        self.__fps_cap = fps_cap
        self.__showfps = False
        self.__dirty = True
        self.__always_draw = always_draw
        self.__font = pygame.font.Font(None, 17)
        self.__run_event = False

        # Variables to hold game engine elements and callbacks
        self.__event_cb = []
        self.__draw_lst = []
        self.__object_hold = {}

        # Game Timers
        self.__active_event_timers = []
        self.__active_event_timers_tick = []

        # Game Clock
        self.clock = pygame.time.Clock()
        self.__tick_time = 0

        # Inspector
        self._inspector = GameInspect(self.__object_hold)

        # Time Profiler Timers
        self.__draw_time = {}
        self.__draw_calls = {}
        self.__event_time = {}
        self.__event_calls = {}
        self.__timer_time = {}
        self.__timer_calls = {}

        # Initialize Py Console
        self.console = GameEngineConsole(self, (0, 0, width, height / 2))

        # Disable Mouse Usage
        # TODO Allow mouse motion on request
        pygame.event.set_blocked(pygame.MOUSEMOTION)

    def set_dirty(self):
        """
        Sets the dirty flag to force the engine to draw the next time
        it enters the draw flag.
        """
        self.__dirty = True

    def get_scene(self):
        """
        Returns the scene object

        @return:    Returns the scene object held by the game engine
        """
        return self.__scene

    def start_event_timer(self, function_cb, time):
        """
        Starts a timer that fires a user event into the queue every "time"
        milliseconds

        @param function_cb:     The function to call when timer fires
        @param time:            Milliseconds between fires
        """
        avail_timer = len(self.__active_event_timers)

        if avail_timer + pygame.USEREVENT < pygame.NUMEVENTS:
            if function_cb not in self.__active_event_timers:
                self.__timer_time[str(function_cb)] = 0
                self.__timer_calls[str(function_cb)] = 0

                self.__active_event_timers.append(function_cb)
                self.__active_event_timers_tick.append(time)
                pygame.time.set_timer(pygame.USEREVENT + avail_timer, time)
            else:
                print "ERROR TIMER IN LIST"
        else:
            print "Ran out of timers :("
            self.stop_event_loop()

    def stop_event_timer(self, function_cb):
        """
        Stops the timer that has id from firing

        @param function_cb:     The function registered with the timer that
                                should be canceled
        """
        try:
            timer_id = self.__active_event_timers.index(function_cb)
        except ValueError:
            return

        pygame.time.set_timer(pygame.USEREVENT + timer_id, 0)
        del self.__active_event_timers[timer_id]
        del self.__active_event_timers_tick[timer_id]

        # Timers have been removed, now need to clear any events
        # already fired and in the queue
        pygame.event.clear(pygame.USEREVENT + timer_id)

    def list_event_timers(self):
        """
        returns a list of configured timers, if the timers has a time of 0 the
        timer is disabled
        """
        timer_list = "Event Timers:\n"
        i = 0
        for timer_item in self.__active_event_timers:
            timer_list += "\t%d: %d\n" % (timer_item,
                                          self.__active_event_timers_tick[i])
            i = i + 1

        return timer_list

    def list_timer_time(self):
        """
        Returns a string representation of the time the game spends
        in each timer callback.
        """
        mystr = "Timer Times:\n\tName\tCalls\tTotal Time\tAvg"
        for key in self.__timer_time:
            timer_times = self.__timer_time[key]
            timer_calls = self.__timer_calls[key]
            if timer_calls == 0:
                avg = 0
            else:
                avg = timer_times / timer_calls

            mystr = "%s\n\t%s\n\t\t%d\t%f\t%f" % \
                    (mystr, key, timer_calls, timer_times, avg)
        return mystr

    def start_main_loop(self):
        """
        Starts the game loop.

        This function does not return until after the game loop exits
        """
        self.__run_event = True
        self._event_loop()

    def _draw(self, tick_time):
        """
        Draws all elements in draw callback to the screen

        @param tick_time:       The amount of time passed since last
                                draw cycle. (should be produced by
                                pygamme.clock.tick method)
        """
        screen = self.screen

        # If console is active, we want to draw console, pausing
        # game drawing (events are still being fired, just no
        # draw updates.
        if self.__version:
            if self.console.active:
                self.console.draw()
                pygame.display.flip()
            else:
                for fnc in self.__draw_lst:
                    start = time()
                    fnc()
                    self.__draw_time[str(fnc)] += time() - start
                    self.__draw_calls[str(fnc)] += 1
                # Print Frame Rate
                if self.__showfps:
                    self.__fps.changeText('FPS: %d' % self.clock.get_fps(),
                                          (255, 255, 255))
                else:
                    self.__fps.changeText('')
                self.__scene.update(tick_time)
                pygame.display.update(self.__scene.draw(screen))
        else:
            if self.console.active:
                self.console.draw()
                pygame.display.flip()
            else:
                for fnc in self.__draw_lst:
                    start = time()
                    fnc(screen, tick_time)
                    self.__draw_time[str(fnc)] += time() - start
                    self.__draw_calls[str(fnc)] += 1
                # Print Frame Rate
                if self.__showfps:
                    text = self.__font.render('FPS: %d' % \
                           self.clock.get_fps(), False, (255, 255, 255),
                           (159, 182, 205))
                    screen.blit(text, (0, 0))
                pygame.display.flip()

    def _event_loop(self):
        """
        The main event loop.
        """
        while self.__run_event:

            event = pygame.event.poll()

            # Handle Game Quit Message
            if event.type == pygame.QUIT:
                self.__run_event = False

            # No-Op sent, draw if set to always draw
            elif event.type == pygame.NOEVENT:
                # Tick even if not drawing
                # We want to pause the cpu from getting into a
                # 100% usage looping on the poll until something
                # becomes dirty
                self.__tick_time += self.clock.tick(self.__fps_cap)
                if self.__always_draw or self.__dirty:
                    self.__dirty = False
                    self._draw(self.__tick_time)
                    self.__tick_time = 0

            # Handle User event Timers
            elif event.type >= pygame.USEREVENT and \
                event.type < pygame.NUMEVENTS:

                timer_id = event.type - pygame.USEREVENT

                # Call timer
                str_rep = str(self.__active_event_timers[timer_id])
                start = time()
                self.__active_event_timers[timer_id]()
                self.__timer_time[str_rep] += time() - start
                self.__timer_calls[str_rep] += 1

            # Check if we should activate the console
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_w \
                    and pygame.key.get_mods() & pygame.KMOD_CTRL:
                self.console.set_active()
                self.set_dirty()

            # Pass event to console
            elif self.console.process_input(event):
                self.set_dirty()

            # Pass events to all others
            else:
                # Make a copy first so that adding events don't get fired
                # right away
                list_cp = self.__event_cb[:]

                # Reverse list so that newest stuff is on top
                # TODO: cache this list
                list_cp.reverse()

                for cb in list_cp:
                    # Fire the event for all in cb and stop
                    # if the callback returns True
                    start = time()
                    retur_val = cb(event)
                    self.__event_time[str(cb)] += time() - start
                    self.__event_calls[str(cb)] += 1

                    if retur_val:
                        break

    def stop_event_loop(self):
        """
        Sends a pygame.QUIT event into the event queue which
        exits the event loop
        """
        pygame.event.post(pygame.event.Event(pygame.QUIT))

    def add_event_callback(self, cb):
        """
        Adds event callback to the event callback stack

        @param cb:  Callback to be added to the stack when events are fired.
        """
        self.__event_time[str(cb)] = 0
        self.__event_calls[str(cb)] = 0
        self.__event_cb.append(cb)

    def remove_event_callback(self, cb):
        """
        Removes an event from the event callback stack

        @param cb:       The callback to remove from the event callback stack
        @return:         Returns true if successful in removing callback
        """
        try:
            self.__event_cb.remove(cb)
            return True
        except:
            return False

    def list_event_callbacks(self):
        """
        Returns a string representation of all events registered with the game
        engine
        """
        event_callbacks = "Event Listeners:\n"
        for eventlst in self.__event_cb:
            event_callbacks = "%s\t%s\n" % (event_callbacks, str(eventlst))
        return event_callbacks

    def list_event_time(self):
        """
        Returns a string representation of the time the game spends
        in each event callback.
        """
        mystr = "Event Times:\n\tName\tCalls\tTotal Time\tAvg"
        for key in self.__event_time:
            event_times = self.__event_time[key]
            event_calls = self.__event_calls[key]
            if event_calls == 0:
                avg = 0
            else:
                avg = event_times / event_calls

            mystr = "%s\n\t%s\n\t\t%d\t%f\t%f" % \
                    (mystr, key, event_calls, event_times, avg)
        return mystr

    def add_draw_callback(self, fnc):
        """
        Adds a callback to the draw list.  Function will be passed the
        game screen it should draw too.

        @param fnc:    The function to call when system is drawing
        """

        self.__draw_time[str(fnc)] = 0
        self.__draw_calls[str(fnc)] = 0
        self.__draw_lst.append(fnc)

    def pop_draw_callback(self):
        """
        Removes top of draw stack and returns it

        @return:         Returns the top callback function that was removed
        """
        return self.__draw_lst.pop()

    def clear_draw_callback(self):
        """
        Empties draw callback stack
        """
        self.__draw_lst = []

    def remove_draw_callback(self, fnc):
        """
        Removes a draw callback from the game engine draw function

        @param fnc:      The callback function to remove
        @return:         Returns true if successful removal of the function
        """
        try:
            self.__draw_lst.remove(fnc)
            return True
        except:
            return False

    def list_draw_callbacks(self):
        """
        Lists all the draw callbacks currently registered with the game engine
        """

        callbacks = "Draw Callbacks:\n"
        for eventlst in self.__draw_lst:
            callbacks += "\t%s\n" % str(eventlst)
        return callbacks

    def list_draw_time(self):
        """
        Returns a string representation of the time the game spends
        in each drawing callback.
        """
        mystr = "Drawing Times:\n\tName\tCalls\tTotal Time\tAvg"
        for key in self.__draw_time:
            draw_times = self.__draw_time[key]
            draw_calls = self.__draw_calls[key]
            if draw_calls == 0:
                avg = 0
            else:
                avg = draw_times / draw_calls

            mystr = "%s\n\t%s\n\t\t%d\t%f\t%f" % \
                    (mystr, key, draw_calls, draw_times, avg)
        return mystr

    def has_object(self, name):
        """
        Returns true if object is stored in game engine

        @param name:     Name of the object to check if exists
        @return:         Returns true if object found
        """
        return name in self.__object_hold

    def add_object(self, name, obj):
        """
        Adds an object to the game engine datastore

        @param name:     The name used to store the object
        @param obj:      The object to store
        """
        self.__object_hold[name] = obj

    def get_object(self, name):
        """
        Returns an object from the game engine datastore

        @param name:     The name of object to return
        @return:         Returns the object
        """
        return self.__object_hold[name]

    def remove_object(self, name):
        """
        Removes an object from the game engine datastore

        @param name:     The name of the object to remove
        """
        del self.__object_hold[name]

    def list_objects(self):
        """
        Returns a sting of registered objects
        """
        objlist = "Objects Registered:\n"
        for eventlst in self.__object_hold:
            objlist += "\t%s\n" % str(eventlst)
        return objlist

    def toggle_fps(self):
        """
        Toggles fps display
        """
        self.__showfps = not self.__showfps

    def art_scale(self, original, expected, width=True):
        if width:
            return int(self.width / float(expected) * float(original))
        else:

            return int(self.height / float(expected) * float(original))
예제 #11
0
 def draw(self):
     Scene.draw(self)
     self.sprite.draw()
예제 #12
0
class GameEngine(object):
    """
    The Fortune Engine GameEngine is a main loop wrapper around pygame.
    It manages the event and drawing loops allowing the user to just
    register for user events and drawing time in the draw loop.
    """
    instance = None

    def __init__(self, width=1200, height=900, always_draw=False,
                 fps_cap=15, version=False, title="FortuneEngine"):
        """
        Constructor for the game engine.

        @param width:        Window width
        @param height:       Window height
        @param always_draw:  Boolean to set the animation mode to always
                             draw vs draw when set_dirty is called
        @param fps_cap:      Sets the framerate cap. Set to 0 to disable
                             the cap. Warning: setting the cap to 0 when
                             always draw = False will cause cpu 100% when
                             not driving.
        @param version:      If true, use new rendering system, false uses
                             only the draw system
        @param title:        Window Title
        """
        GameEngine.instance = self
        pygame.init()
        pygame.mouse.set_visible(False)
        self.__version = version #true is new, false is old

        # Window Settings
        self.width = width
        self.height = height
        size = width, height
        self.screen = pygame.display.set_mode(size)
        pygame.display.set_caption(title)
        self.__fps = DrawableFontObject("", pygame.font.Font(None, 17))
        self.__fps.setPosition(0, 0)
        self.__scene = Scene(self.__fps)

        # Engine Internal Variables
        self.__fps_cap = fps_cap
        self.__showfps = False
        self.__dirty = True
        self.__always_draw = always_draw
        self.__font = pygame.font.Font(None, 17)
        self.__run_event = False

        # Variables to hold game engine elements and callbacks
        self.__event_cb = []
        self.__draw_lst = []
        self.__object_hold = {}


        # Game Timers
        self.__active_event_timers = []
        self.__active_event_timers_tick = []

        # Game Clock
        self.clock = pygame.time.Clock()
        self.__tick_time = 0

        # Inspector
        self._inspector = GameInspect(self.__object_hold)

        # Time Profiler Timers
        self.__draw_time = {}
        self.__draw_calls = {}
        self.__event_time = {}
        self.__event_calls = {}
        self.__timer_time = {}
        self.__timer_calls = {}

        # Initialize Py Console
        self.console = GameEngineConsole(self, (0, 0, width, height / 2))

        # Disable Mouse Usage
        # TODO Allow mouse motion on request
        pygame.event.set_blocked(pygame.MOUSEMOTION)

    def set_dirty(self):
        """
        Sets the dirty flag to force the engine to draw the next time
        it enters the draw flag.
        """
        self.__dirty = True

    def get_scene(self):
        """
        Returns the scene object

        @return:    Returns the scene object held by the game engine
        """
        return self.__scene

    def start_event_timer(self, function_cb, time):
        """
        Starts a timer that fires a user event into the queue every "time"
        milliseconds

        @param function_cb:     The function to call when timer fires
        @param time:            Milliseconds between fires
        """
        avail_timer = len(self.__active_event_timers)

        if avail_timer + pygame.USEREVENT < pygame.NUMEVENTS:
            if function_cb not in self.__active_event_timers:
                self.__timer_time[str(function_cb)] = 0
                self.__timer_calls[str(function_cb)] = 0

                self.__active_event_timers.append(function_cb)
                self.__active_event_timers_tick.append(time)
                pygame.time.set_timer(pygame.USEREVENT + avail_timer, time)
            else:
                print "ERROR TIMER IN LIST"
        else:
            print "Ran out of timers :("
            self.stop_event_loop()

    def stop_event_timer(self, function_cb):
        """
        Stops the timer that has id from firing

        @param function_cb:     The function registered with the timer that
                                should be canceled
        """
        try:
            timer_id = self.__active_event_timers.index(function_cb)
        except ValueError:
            return

        pygame.time.set_timer(pygame.USEREVENT + timer_id, 0)
        del self.__active_event_timers[timer_id]
        del self.__active_event_timers_tick[timer_id]

        # Timers have been removed, now need to clear any events
        # already fired and in the queue
        pygame.event.clear(pygame.USEREVENT + timer_id)

    def list_event_timers(self):
        """
        returns a list of configured timers, if the timers has a time of 0 the
        timer is disabled
        """
        timer_list = "Event Timers:\n"
        i = 0
        for timer_item in self.__active_event_timers:
            timer_list += "\t%d: %d\n" % (timer_item,
                          self.__active_event_timers_tick[i])
            i = i + 1

        return timer_list

    def list_timer_time(self):
        """
        Returns a string representation of the time the game spends
        in each timer callback.
        """
        mystr = "Timer Times:\n\tName\tCalls\tTotal Time\tAvg"
        for key in self.__timer_time:
            timer_times = self.__timer_time[key]
            timer_calls = self.__timer_calls[key]
            if timer_calls == 0:
                avg = 0
            else:
                avg = timer_times / timer_calls

            mystr = "%s\n\t%s\n\t\t%d\t%f\t%f" % \
                    (mystr, key, timer_calls, timer_times, avg)
        return mystr

    def start_main_loop(self):
        """
        Starts the game loop.

        This function does not return until after the game loop exits
        """
        self.__run_event = True
        self._event_loop()

    def _draw(self, tick_time):
        """
        Draws all elements in draw callback to the screen

        @param tick_time:       The amount of time passed since last
                                draw cycle. (should be produced by
                                pygamme.clock.tick method)
        """
        screen = self.screen

        # If console is active, we want to draw console, pausing
        # game drawing (events are still being fired, just no
        # draw updates.
        if self.__version:
            if self.console.active:
                self.console.draw()
                pygame.display.flip()
            else:
                for fnc in self.__draw_lst:
                    start = time()
                    fnc()
                    self.__draw_time[str(fnc)] += time() - start
                    self.__draw_calls[str(fnc)] += 1
                # Print Frame Rate
                if self.__showfps:
                    self.__fps.changeText('FPS: %d' % self.clock.get_fps(),
                                                      (255, 255, 255))
                else:
                    self.__fps.changeText('')
                self.__scene.update(tick_time)
                pygame.display.update(self.__scene.draw(screen))
        else:
            if self.console.active:
                self.console.draw()
                pygame.display.flip()
            else:
                for fnc in self.__draw_lst:
                    start = time()
                    fnc(screen, tick_time)
                    self.__draw_time[str(fnc)] += time() - start
                    self.__draw_calls[str(fnc)] += 1
                # Print Frame Rate
                if self.__showfps:
                    text = self.__font.render('FPS: %d' % \
                           self.clock.get_fps(), False, (255, 255, 255),
                           (159, 182, 205))
                    screen.blit(text, (0, 0))
                pygame.display.flip()

    def _event_loop(self):
        """
        The main event loop.
        """
        while self.__run_event:

            event = pygame.event.poll()

            # Handle Game Quit Message
            if event.type == pygame.QUIT:
                self.__run_event = False

            # No-Op sent, draw if set to always draw
            elif event.type == pygame.NOEVENT:
                # Tick even if not drawing
                # We want to pause the cpu from getting into a
                # 100% usage looping on the poll until something
                # becomes dirty
                self.__tick_time += self.clock.tick(self.__fps_cap)
                if self.__always_draw or self.__dirty:
                    self.__dirty = False
                    self._draw(self.__tick_time)
                    self.__tick_time = 0


            # Handle User event Timers
            elif event.type >= pygame.USEREVENT and \
                event.type < pygame.NUMEVENTS:

                timer_id = event.type - pygame.USEREVENT

                # Call timer
                str_rep = str(self.__active_event_timers[timer_id])
                start = time()
                self.__active_event_timers[timer_id]()
                self.__timer_time[str_rep] += time() - start
                self.__timer_calls[str_rep] += 1

            # Check if we should activate the console
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_w \
                    and pygame.key.get_mods() & pygame.KMOD_CTRL:
                self.console.set_active()
                self.set_dirty()

            # Pass event to console
            elif self.console.process_input(event):
                self.set_dirty()

            # Pass events to all others
            else:
                # Make a copy first so that adding events don't get fired
                # right away
                list_cp = self.__event_cb[:]

                # Reverse list so that newest stuff is on top
                # TODO: cache this list
                list_cp.reverse()

                for cb in list_cp:
                    # Fire the event for all in cb and stop
                    # if the callback returns True
                    start = time()
                    retur_val = cb(event)
                    self.__event_time[str(cb)] += time() - start
                    self.__event_calls[str(cb)] += 1

                    if retur_val:
                        break

    def stop_event_loop(self):
        """
        Sends a pygame.QUIT event into the event queue which
        exits the event loop
        """
        pygame.event.post(pygame.event.Event(pygame.QUIT))

    def add_event_callback(self, cb):
        """
        Adds event callback to the event callback stack

        @param cb:  Callback to be added to the stack when events are fired.
        """
        self.__event_time[str(cb)] = 0
        self.__event_calls[str(cb)] = 0
        self.__event_cb.append(cb)

    def remove_event_callback(self, cb):
        """
        Removes an event from the event callback stack

        @param cb:       The callback to remove from the event callback stack
        @return:         Returns true if successful in removing callback
        """
        try:
            self.__event_cb.remove(cb)
            return True
        except:
            return False

    def list_event_callbacks(self):
        """
        Returns a string representation of all events registered with the game
        engine
        """
        event_callbacks = "Event Listeners:\n"
        for eventlst in self.__event_cb:
            event_callbacks = "%s\t%s\n" % (event_callbacks, str(eventlst))
        return event_callbacks

    def list_event_time(self):
        """
        Returns a string representation of the time the game spends
        in each event callback.
        """
        mystr = "Event Times:\n\tName\tCalls\tTotal Time\tAvg"
        for key in self.__event_time:
            event_times = self.__event_time[key]
            event_calls = self.__event_calls[key]
            if event_calls == 0:
                avg = 0
            else:
                avg = event_times / event_calls

            mystr = "%s\n\t%s\n\t\t%d\t%f\t%f" % \
                    (mystr, key, event_calls, event_times, avg)
        return mystr

    def add_draw_callback(self, fnc):
        """
        Adds a callback to the draw list.  Function will be passed the
        game screen it should draw too.

        @param fnc:    The function to call when system is drawing
        """

        self.__draw_time[str(fnc)] = 0
        self.__draw_calls[str(fnc)] = 0
        self.__draw_lst.append(fnc)

    def pop_draw_callback(self):
        """
        Removes top of draw stack and returns it

        @return:         Returns the top callback function that was removed
        """
        return self.__draw_lst.pop()

    def clear_draw_callback(self):
        """
        Empties draw callback stack
        """
        self.__draw_lst = []

    def remove_draw_callback(self, fnc):
        """
        Removes a draw callback from the game engine draw function

        @param fnc:      The callback function to remove
        @return:         Returns true if successful removal of the function
        """
        try:
            self.__draw_lst.remove(fnc)
            return True
        except:
            return False

    def list_draw_callbacks(self):
        """
        Lists all the draw callbacks currently registered with the game engine
        """

        callbacks = "Draw Callbacks:\n"
        for eventlst in self.__draw_lst:
            callbacks += "\t%s\n" % str(eventlst)
        return callbacks

    def list_draw_time(self):
        """
        Returns a string representation of the time the game spends
        in each drawing callback.
        """
        mystr = "Drawing Times:\n\tName\tCalls\tTotal Time\tAvg"
        for key in self.__draw_time:
            draw_times = self.__draw_time[key]
            draw_calls = self.__draw_calls[key]
            if draw_calls == 0:
                avg = 0
            else:
                avg = draw_times / draw_calls

            mystr = "%s\n\t%s\n\t\t%d\t%f\t%f" % \
                    (mystr, key, draw_calls, draw_times, avg)
        return mystr

    def has_object(self, name):
        """
        Returns true if object is stored in game engine

        @param name:     Name of the object to check if exists
        @return:         Returns true if object found
        """
        return name in self.__object_hold

    def add_object(self, name, obj):
        """
        Adds an object to the game engine datastore

        @param name:     The name used to store the object
        @param obj:      The object to store
        """
        self.__object_hold[name] = obj

    def get_object(self, name):
        """
        Returns an object from the game engine datastore

        @param name:     The name of object to return
        @return:         Returns the object
        """
        return self.__object_hold[name]

    def remove_object(self, name):
        """
        Removes an object from the game engine datastore

        @param name:     The name of the object to remove
        """
        del self.__object_hold[name]

    def list_objects(self):
        """
        Returns a sting of registered objects
        """
        objlist = "Objects Registered:\n"
        for eventlst in self.__object_hold:
            objlist += "\t%s\n" % str(eventlst)
        return objlist

    def toggle_fps(self):
        """
        Toggles fps display
        """
        self.__showfps = not self.__showfps

    def art_scale(self, original, expected, width=True):
        if width:
            return int(self.width / float(expected) * float(original))
        else:

            return int(self.height / float(expected) * float(original))
예제 #13
0
def main():
	# 初始化
	pygame.init()
	screen = pygame.display.set_mode((WIDTH, HEIGHT))
	pygame.display.set_caption("T-Rex Rush-公众号: Charles的皮卡丘")
	clock = pygame.time.Clock()
	# 得分
	score = 0
	# 加载一些素材
	jump_sound = pygame.mixer.Sound("./music/jump.wav")
	jump_sound.set_volume(6)
	die_sound = pygame.mixer.Sound("./music/die.wav")
	die_sound.set_volume(6)
	pygame.mixer.init()
	pygame.mixer.music.load("./music/bg_music.mp3")
	pygame.mixer.music.set_volume(0.6)
	pygame.mixer.music.play(-1)
	font = pygame.font.Font('./font/simkai.ttf', 20)
	# 实例化
	dinosaur = Dinosaur(WIDTH, HEIGHT)
	scene = Scene(WIDTH, HEIGHT)
	plants = pygame.sprite.Group()
	pteras = pygame.sprite.Group()
	# 产生障碍物事件
	GenPlantEvent = pygame.constants.USEREVENT + 0
	pygame.time.set_timer(GenPlantEvent, 1500)
	GenPteraEvent = pygame.constants.USEREVENT + 1
	pygame.time.set_timer(GenPteraEvent, 5000)
	# 游戏是否结束了
	running = True
	# 是否可以产生障碍物flag
	flag_plant = False
	flag_ptera = False
	t0 = time.time()
	# 主循环
	while running:
		for event in pygame.event.get():
			if event.type == QUIT:
				sys.exit()
				pygame.quit()
			if event.type == GenPlantEvent:
				flag_plant = True
			if event.type == GenPteraEvent:
				if score > 50:
					flag_ptera = True
		key_pressed = pygame.key.get_pressed()
		if key_pressed[pygame.K_SPACE]:
			dinosaur.is_jumping = True
			jump_sound.play()
		screen.fill(BACKGROUND)
		time_passed = time.time() - t0
		t0 = time.time()
		# 场景
		scene.move()
		scene.draw(screen)
		# 小恐龙
		dinosaur.is_running = True
		if dinosaur.is_jumping:
			dinosaur.be_afraid()
			dinosaur.jump(time_passed)
		dinosaur.draw(screen)
		# 障碍物-植物
		if random.random() < sigmoid(score) and flag_plant:
			plant = Plant(WIDTH, HEIGHT)
			plants.add(plant)
			flag_plant = False
		for plant in plants:
			plant.move()
			if dinosaur.rect.left > plant.rect.right and not plant.added_score:
				score += 1
				plant.added_score = True
			if plant.rect.right < 0:
				plants.remove(plant)
				continue
			plant.draw(screen)
		# 障碍物-飞龙
		if random.random() < sigmoid(score) and flag_ptera:
			if len(pteras) > 1:
				continue
			ptera = Ptera(WIDTH, HEIGHT)
			pteras.add(ptera)
			flag_ptera = False
		for ptera in pteras:
			ptera.move()
			if dinosaur.rect.left > ptera.rect.right and not ptera.added_score:
				score += 5
				ptera.added_score = True
			if ptera.rect.right < 0:
				pteras.remove(ptera)
				continue
			ptera.draw(screen)
		# 碰撞检测
		if pygame.sprite.spritecollide(dinosaur, plants, False) or pygame.sprite.spritecollide(dinosaur, pteras, False):
			die_sound.play()
			running = False
		# 显示得分
		score_text = font.render("Score: "+str(score), 1, (0, 0, 0))
		screen.blit(score_text, [10, 10])
		pygame.display.flip()
		clock.tick(60)
	res = show_gameover(screen)
	return res
예제 #14
0
class App:
    def __init__(self, debug_mode=True):
        pyxel.init(200, 200, caption="ADV")
        pyxel.mouse(visible=True)
        pyxel.load("../asset.pyxres")

        self.debug_mode = debug_mode

        messages = self.get_messages()

        self.scene = Scene(messages, debug_mode=self.debug_mode)

        pyxel.run(self.update, self.draw)

    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()

        if self.scene.flags["clear"]:
            return

        self.scene.update()

        if pyxel.btnp(pyxel.MOUSE_RIGHT_BUTTON):
            self.scene.click_mouse()

    def draw(self):
        self.draw_back_ground()
        self.scene.draw()
        self.debug_info()

    def draw_back_ground(self):
        pyxel.cls(15)
        h = pyxel.height / 5
        pyxel.rect(0, 4 * h, pyxel.width, h, 4)

        pyxel.text(125, 80, "\ Escape here! /", 0)
        pyxel.text(20, 20, "Right click to check.", 0)

    def get_messages(self):
        messages = []

        def draw_chest():
            pyxel.blt(x=30, y=136, img=0, u=0, v=32, w=48, h=24, colkey=7)

        m = Message(x=30,
                    y=136,
                    h=24,
                    w=48,
                    scene_name="room1",
                    flag_name=f"chest",
                    precondition_name=None,
                    draw_function=draw_chest,
                    text=f"You open the chest.\nNothing in it.")
        messages.append(m)

        def draw_potion():
            pyxel.blt(x=40, y=128, img=0, u=8, v=16, w=8, h=8, colkey=7)

        m = Message(x=40,
                    y=128,
                    h=8,
                    w=8,
                    scene_name="room1",
                    flag_name=f"portion",
                    precondition_name=None,
                    draw_function=draw_potion,
                    text=f"This is a portion.\nIt smells bad...")
        messages.append(m)

        def draw_meat():
            pyxel.blt(x=60, y=128, img=0, u=24, v=8, w=8, h=8, colkey=7)

        m = Message(x=60,
                    y=128,
                    h=8,
                    w=8,
                    scene_name="room1",
                    flag_name=f"meat",
                    precondition_name=None,
                    draw_function=draw_meat,
                    text=f"This is a meat.\nYou eat it.\nA key is in it.")
        messages.append(m)

        def draw_door():
            x, y = 130, 90
            w, h = 50, 70
            pyxel.rect(x, y, w, h, 12)
            pyxel.rect(x + 5, y + 5, w - 10, h // 2 - 10, 13)
            pyxel.rectb(x + 5, y + 5, w - 10, h // 2 - 10, 5)
            pyxel.rect(x + 5, y + h // 2 + 5, w - 10, h // 2 - 10, 13)
            pyxel.rectb(x + 5, y + h // 2 + 5, w - 10, h // 2 - 10, 5)
            pyxel.circ(x + 3 * w // 4, y + h // 2, 2, 9)

        m = Message(x=130,
                    y=90,
                    h=70,
                    w=50,
                    scene_name="room1",
                    flag_name=f"clear",
                    precondition_name=f"meat",
                    draw_function=draw_door,
                    text=f"You unlock the door.\nWell done!\n\"Q\" to quit.")
        messages.append(m)
        return messages

    def debug_info(self):
        if not self.debug_mode:
            return
        info = f"mouse x:{pyxel.mouse_x:.1f}, y:{pyxel.mouse_y:.1f}"
        pyxel.text(0, 0, info, 7)
    def loop(self):
        pygame.mixer.music.play(-1)

        while self.is_running:
            # HUD
            start_button = Button(0, 30, path_buttonStart)
            ok_button = Button(0, 30, path_buttonOk)
            game_name = Button(0, 250, path_gameName)
            start_text = Button(0, 100, path_textStart)
            end_text = Button(0, 100, path_textEnd)

            # Playground
            player = Player(-150, 0, 51, 36)
            bg = Scene(path_bg, 0, 100, 864, 768)
            ground = Scene(path_ground, 0, -368, 900, 168)
            pipe_group = []
            last_pipe = pygame.time.get_ticks() - pipe_frequency

            restart = False
            self.game_over = False
            self.flying = False
            self.hit_played = False
            game_name.active = True
            start_button.active = True
            start_text.active = True
            end_text.active = False
            ok_button.active = False

            self.score = 0

            # =======
            # In-game
            while (not self.game_over or not restart) and self.is_running:
                # =======
                # Events
                is_flying = False
                for event in pygame.event.get():
                    if event.type == QUIT:
                        self.is_running = False

                    if event.type == KEYDOWN:
                        if self.game_over:
                            restart = True

                        is_flying = is_flying | event.key == K_UP

                    if event.type == MOUSEBUTTONDOWN:
                        if self.game_over:
                            restart = ok_button.isHovered()

                        is_flying = is_flying | pygame.mouse.get_pressed(3)[0]
                        is_flying = is_flying & start_button.isHovered()

                if is_flying and not self.flying and not self.game_over:
                    self.flying = True
                    start_button.active = False
                    start_text.active = False
                    game_name.active = False

                # =======================
                # Controller
                player.move_handling(self.flying, self.game_over, self.flap_sound)

                # ==============
                # Pipes handing
                if self.flying is True and self.game_over is False:
                    # Pipe random generation
                    time_now = pygame.time.get_ticks()
                    if time_now - last_pipe > pipe_frequency:
                        pipe_height = random.randint(-150, 250)
                        btm_pipe = Pipe(display[0], pipe_height, 78, 568, False)
                        top_pipe = Pipe(display[0], pipe_height, 78, 568, True)
                        pipe_group.append(btm_pipe)
                        pipe_group.append(top_pipe)
                        last_pipe = time_now
                    # Delete out of screen pipes
                    if pipe_group[0].x < -350:
                        pipe_group.pop(0)
                    # Scrolling pipes
                    for i in range(0, len(pipe_group)):
                        pipe_group[i].scrolling()

                # ================
                # Check collision
                for i in range(0, len(pipe_group)):
                    if check_collision(player, pipe_group[i]):
                        self.game_over = True
                if player.y >= 425:
                    self.game_over = True
                if player.y <= -270:
                    self.game_over = True
                    self.flying = False
                if self.game_over:
                    end_text.active = True
                    ok_button.active = True

                # ============
                # Check score
                if len(pipe_group) > 0:
                    if player.x - player.width / 2 > pipe_group[0].x - pipe_group[0].width / 2 and \
                            player.x + player.width / 2 < pipe_group[0].x + pipe_group[0].width / 2 and \
                            self.pass_pipe is False:
                        self.pass_pipe = True
                    if self.pass_pipe is True:
                        if player.x - player.width / 2 > pipe_group[0].x + pipe_group[0].width / 2:
                            self.score += 1
                            self.score_sound.play()
                            self.pass_pipe = False

                # =====================
                # Scrolling the ground
                if not self.game_over:
                    ground.scrolling()

                # =======
                # Sounds
                if self.game_over is True:
                    if self.hit_played is False:
                        self.hit_sound.play()
                        self.die_sound.play()
                        self.hit_played = True

                # =======
                # Render
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
                glUseProgram(shader.program)
                bg.draw()
                for i in range(0, len(pipe_group)):
                    pipe_group[i].draw()
                ground.draw()
                player.draw()

                # Draw Menu
                game_name.draw()
                start_button.draw()
                start_text.draw()
                end_text.draw()
                ok_button.draw()

                # Draw Score
                i = 0
                numbers = list(str(self.score))
                length_numbers = len(numbers)
                for number in numbers:
                    path_button_score = "Textures/" + number + ".png"
                    score_text = Scene(path_button_score, 0 - (length_numbers - 1) * 25 + i * 40, 350, 36, 54)
                    score_text.draw()

                    i = i + 1

                glUseProgram(0)
                pygame.display.flip()
                self.timer.tick(fps)
예제 #16
0
파일: Main.py 프로젝트: xgxdmx/Chrome_Dino
def main():
    # 游戏程序初始化
    pygame.init()
    screen = pygame.display.set_mode((Width, Height))
    pygame.display.set_caption("梦の彼方")
    ico = pygame.image.load(icon_img).convert_alpha()
    pygame.display.set_icon(ico)
    Clock = pygame.time.Clock()
    # 得分初始化
    score = 0
    # 载入游戏素材并初始化
    Jump_Sound = pygame.mixer.Sound("./music/jump.wav")
    Jump_Sound.set_volume(10)
    Die_Sound = pygame.mixer.Sound("./music/die.wav")
    Die_Sound.set_volume(10)
    pygame.mixer.init()
    pygame.mixer.music.load(Background_Music[Music_Count])  # 背景音乐
    pygame.mixer.music.set_volume(5)
    pygame.mixer.music.play(-1)
    font = pygame.font.Font("./fonts/FZSJ-TXJW.TTF", 30)
    # 角色、背景、障碍物实例化
    dinosaur = Dinosaur(Width, Height)
    scene = Scene(speed, Width, Height)
    plants = pygame.sprite.Group()
    pteras = pygame.sprite.Group()
    # 产生障碍物事件
    GenPlantEvent = pygame.constants.USEREVENT + 0
    pygame.time.set_timer(GenPlantEvent, 2300)
    GenPteraEvent = pygame.constants.USEREVENT + 1
    pygame.time.set_timer(GenPteraEvent, 5000)
    # 判断游戏是否结束
    Running = True
    # 判断是否可以产生障碍物
    Flag_Plant = False
    Flag_Ptera = False
    time0 = time.time()
    # 主循环
    while Running:
        # 计时
        total_time = 0
        taken_time = pygame.time.get_ticks()  # 获取时间
        left_time = total_time * 60000 + taken_time  # 毫秒
        time_min = left_time // 60000
        time_sec = left_time % 60000 // 1000
        time_text = str(time_min).zfill(2) + ':' + str(time_sec).zfill(2)
        time_font = pygame.font.Font("./fonts/FZSJ-TXJW.TTF", 30)
        time_image = time_font.render("Time:" + time_text, True, (0, 0, 0))
        screen.blit(time_image, [600, 10])
        # 显示得分
        score_text = font.render("Score:" + str(score), 1, (0, 0, 0))
        screen.blit(score_text, [30, 10])
        Probability_text = font.render("障碍物概率:" + str(Probability_2), 1,
                                       (0, 0, 0))
        screen.blit(Probability_text, [210, 10])
        pygame.display.flip()
        Clock.tick(60)
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
                pygame.quit()
            if event.type == GenPlantEvent:
                Flag_Plant = True
            if event.type == GenPteraEvent:
                if score > 5:
                    Flag_Ptera = True
            # 实现鼠标点击恐龙跳跃
            if event.type == MOUSEBUTTONDOWN:
                dinosaur.is_jumping = True
                dinosaur.is_jumping = True
                Jump_Sound.play()
        # 实现空格恐龙跳跃
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_SPACE]:
            dinosaur.is_jumping = True
            dinosaur.is_jumping = True
            Jump_Sound.play()
        if key_pressed[pygame.K_ESCAPE]:
            Running = False
        screen.fill(Background_Colour)
        Time_Passed = time.time() - time0
        time0 = time.time()
        # 场景
        scene.move()
        scene.draw(screen)
        # 小恐龙
        dinosaur.is_running = True
        if dinosaur.is_jumping:
            dinosaur.be_afraid()
            dinosaur.jump(Time_Passed)
        dinosaur.draw(screen)
        # 障碍物——植物
        if random.random() < Obstache_Probability(score, Grade) and Flag_Plant:
            plant = Plant(speed_plants, Width, Height)
            plants.add(plant)
            Flag_Plant = False
        for plant in plants:
            plant.move()
            if dinosaur.rect.left > plant.rect.right and not plant.added_score:
                score += 1
                plant.added_score = True
            if plant.rect.right < 0:
                plants.remove(plant)
                continue
            plant.draw(screen)
        # 障碍物——翼龙
        if random.random() < Obstache_Probability(score, Grade) and Flag_Ptera:
            if len(pteras) > 5:
                continue
            ptera = Ptera(speed_ptera, Width, Height)
            pteras.add(ptera)
            Flag_Ptera = False
        for ptera in pteras:
            ptera.move()
            if dinosaur.rect.left > ptera.rect.right and not ptera.added_score:
                score += 5
                ptera.added_score = True
            if ptera.rect.right < 0:
                pteras.remove(ptera)
                continue
            ptera.draw(screen)
            Flag_Plant = False
        # 碰撞检测
        if pygame.sprite.spritecollide(dinosaur, plants,
                                       False) or pygame.sprite.spritecollide(
                                           dinosaur, pteras, False):
            Die_Sound.play()
            Running = False
    res = Show_GameOver(screen, score_text, time_image)
    return res