示例#1
0
def main():

    pg.init()

    resolution = (1200, 900)
    window = pg.display.set_mode(resolution, pg.DOUBLEBUF | pg.RESIZABLE)
    pg.display.set_caption("pathfinder")

    map = Terrain(8, 11, 100)
    # format (y, x)
    map.set_target([1, 6])
    pawn = Pathfinder([6, 6], map.grid)

    clock = pg.time.Clock()
    run_flag = True

    while run_flag:
        clock.tick(20)

        for event in pg.event.get():
            if event.type == pg.QUIT:
                run_flag = False
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_w:
                    map.add_block_manually(pg.mouse.get_pos())
                if event.key == pg.K_e:
                    map.set_target_manually(pg.mouse.get_pos())
                if event.key == pg.K_q:
                    map.free_block_manually(pg.mouse.get_pos())

        window.fill((120, 120, 120))
        map.draw(window)
        pg.display.update()

        pawn.make_move(map.grid, window, map)
示例#2
0
class World:
    def __init__(self, window, gamers):
        self.terrain = Terrain(1200)
        self.worms = []
        self.gamers = gamers
        for i in range(len(gamers)):
            self.worms += [
                Worm(300 + i * 200,
                     self.terrain.get_level(300 + i * 200) + 5, gamers[i], i)
            ]
        self.rockets = []
        self.window = window
        self.control = []

    def add_control(self, control):
        self.control = control

    def explode(self, x, y, type):
        self.terrain.explode(x, y, type)
        if self.control.music_control.playing:
            self.explosion_sound(type)
        for w in self.worms:
            w.explode(x, y, self.terrain, self)

    def draw(self, window):
        self.terrain.draw(window)
        for w in self.worms:
            w.draw(window)
        self.control.frame.draw()
        self.control.draw_pointer()

    def explosion_sound(self, type):
        if type == 0:
            fire = pygame.mixer.Sound("explosion1.wav")
        if type == 1:
            fire = pygame.mixer.Sound("explosion2.wav")
        if type == 2:
            fire = pygame.mixer.Sound("explosion3.wav")
        pygame.mixer.Sound.play(fire, loops=0)
示例#3
0
文件: main.py 项目: Dejmas/Terrain
class Window(pyglet.window.Window):


    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        pyglet.clock.schedule_interval(self.update, 1./60)
        self.strafe = [0, 0]
        def fps(dt): print 'FPS is %f' % pyglet.clock.get_fps()
        pyglet.clock.schedule_interval(fps, 2)

        # Current (x, y, z) position in the world, specified with floats. Note
        # that, perhaps unlike in class, the y-axis is the vertical axis.
        self.position = (12, 8, 12)
        self.press = {}
        self.press["light"] = 0

        # First element is rotation of the player in the x-z plane (ground
        # plane) measured from the z-axis down. The second is the rotation
        # angle from the ground plane up. Rotation is in degrees.
        #
        # The vertical plane rotation ranges from -90 (looking straight down) to
        # 90 (looking straight up). The horizontal rotation range is unbounded.
        self.rotation = (0, 0)
        self.reticle = None
        
        self.t = Terrain(a=33,water_line=1.5,generate=False)
        self.spin = 180
        self.fps = pyglet.clock.ClockDisplay()
        #self.skybox = SkyBox.fromDir("../example/texture/bluesky", "bluesky")
        #self.skybox = SkyBox.fromDir("../example/texture/lake2", "jajlake2")
        self.kostka = Kostka(self.t) 

    def set_exclusive_mouse(self, exclusive):
        """ If `exclusive` is True, the game will capture the mouse, if False
        the game will ignore the mouse.

        """
        super(Window, self).set_exclusive_mouse(exclusive)
        self.exclusive = exclusive

    def _update(self, dt):
        """ Private implementation of the `update()` method. This is where most
        of the motion logic lives, along with gravity and collision detection.

        Parameters
        ----------
        dt : float
            The change in time since the last call.

        """
        # walking
        speed = 5
        d = dt * speed # distance covered this tick.
        dx, dy, dz = self.get_motion_vector()
        # New position in space, before accounting for gravity.
        dx, dy, dz = dx * d, dy * d, dz * d
        # collisions
        x, y, z = self.position
        self.position = (x + dx, y + dy, z + dz)

        self.kostka.update(dt)

    def update( self, dt ):
        self._update(dt)

    def get_motion_vector(self):
        """ Returns the current motion vector indicating the velocity of the
        player.

        Returns
        -------
        vector : tuple of len 3
            Tuple containing the velocity in x, y, and z respectively.

        """
        if any(self.strafe):
            x, y = self.rotation
            strafe = degrees(atan2(*self.strafe))
            y_angle = radians(y)
            x_angle = radians(x + strafe)
            m = cos(y_angle)
            dy = sin(y_angle)
            if self.strafe[1]:
                # Moving left or right.
                dy = 0.0
                m = 1
            if self.strafe[0] > 0:
                # Moving backwards.
                dy *= -1
            # When you are flying up or down, you have less left and right
            # motion.
            dx = cos(x_angle) * m
            dz = sin(x_angle) * m
            # else:
            #     dy = 0.0
            #     dx = cos(x_angle)
            #     dz = sin(x_angle)
        else:
            dy = 0.0
            dx = 0.0
            dz = 0.0
        return (dx, dy, dz)

    def on_resize(self, width, height):
        """ Called when the window is resized to a new `width` and `height`.

        """
        # label
        #self.label.y = height - 10
        # reticle
        if self.reticle:
            self.reticle.delete()
        x, y = self.width / 2, self.height / 2
        n = 10
        self.reticle = pyglet.graphics.vertex_list(4,
            ('v2i', (x - n, y, x + n, y, x, y - n, x, y + n))
        )

    def on_draw(self):
        self.clear()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)  
        self.water_line = 1.5
        self.water_color = (0.3,0.3,1,1)
        
        self.set_3d()
        glTranslatef(-16, 0, -16)
        
        # kostka

        self.t.draw(self.position[1])
        self.kostka.draw()

        glPopMatrix() # set_3d camera transf
        self.set_2d()
        glColor3d(0, 0, 0)
        self.fps.draw()

    def set_2d(self):
        """ Configure OpenGL to draw in 2d.

        """
        width, height = self.get_size()
        glDisable(GL_DEPTH_TEST)
        glDisable(GL_LIGHTING)
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, width, 0, height, -1, 1)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

    def set_3d(self):
        """ Configure OpenGL to draw in 3d.

        """
        width, height = self.get_size()
        glEnable(GL_DEPTH_TEST)
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(65.0, width / float(height), 0.1, 500.0)
        # gluPerspective(65, width / float(height), 15, 0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        # set camera
        glPushMatrix()
        rx, ry = self.rotation
        glRotatef(rx, 0, 1, 0)
        glRotatef(-ry, cos(radians(rx)), 0, sin(radians(rx)))
        x, y, z = self.position
        #y = self.t.Height(x, z, floating=True)+.3
        glTranslatef(-x, -y, -z)
        #self.skybox.draw(yrot=rx, xrot=-ry)


        # set lightning source
        self.spin += self.press["light"]
        self.spin %= 360
        glPushMatrix();
        x = lambda s : sin(radians(s))*30
        z = lambda s : cos(radians(s))*30
        self.t.lightPos = ( x(self.spin), 15., z(self.spin) )
        #self.shader.uniform3fv("lightPos[0]", *[x(self.spin), 15, z(self.spin)])
        #self.shader.uniform3fv("lightPos[1]", *[x(self.spin+120), 15, z(self.spin+120)])
        #self.shader.uniform3fv("lightPos[2]", *[x(self.spin+240), 15, z(self.spin+240)])
        glTranslatef(0, 25, 0)
        glRotated(self.spin, 1.0, 0.0, 0.0);

        glTranslated (0.0, 0.0, 30.0);
        glLightfv(GL_LIGHT0, GL_POSITION, vec(0, 0, 0, 1))
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, vec(0, -1, 0))
        glDisable (GL_LIGHTING);
        glColor3f (0.0, 1.0, 1.0);
        glutWireCube (2.0);
        glEnable (GL_LIGHTING);
        glPopMatrix()

    def on_mouse_press(self, x, y, button, modifiers):
        """ Called when a mouse button is pressed. See pyglet docs for button
        amd modifier mappings.

        Parameters
        ----------
        x, y : int
            The coordinates of the mouse click. Always center of the screen if
            the mouse is captured.
        button : int
            Number representing mouse button that was clicked. 1 = left button,
            4 = right button.
        modifiers : int
            Number representing any modifying keys that were pressed when the
            mouse button was clicked.

        """
        if self.exclusive:
            pass
        else:
            self.set_exclusive_mouse(True)

    def on_mouse_motion(self, x, y, dx, dy):
        """ Called when the player moves the mouse.

        Parameters
        ----------
        x, y : int
            The coordinates of the mouse click. Always center of the screen if
            the mouse is captured.
        dx, dy : float
            The movement of the mouse.

        """
        if self.exclusive:
            m = 0.15
            x, y = self.rotation
            x, y = x + dx * m, y + dy * m
            y = max(-90, min(90, y))
            self.rotation = (x, y)

    def on_key_press( self, symbol, modifier ):
        global piece, bottom

        if symbol == key.A:
            self.strafe[1] -= 1
        elif symbol == key.W:
            self.strafe[0] -= 1
        elif symbol == key.S:
            self.strafe[0] += 1
        elif symbol == key.D:
            self.strafe[1] += 1

        elif symbol == key.UP :
            self.kostka.speed += .1
        elif symbol == key.DOWN :
            self.kostka.speed -= .1 
        elif symbol == key.LEFT :
            self.kostka.input[0] = True
        elif symbol == key.RIGHT :
            self.kostka.input[1] = True

        elif symbol == key.F :
            global WIREFRAME
            WIREFRAME = not WIREFRAME
            if WIREFRAME :
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
            else :
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
        elif symbol == key.N :
            self.t = Terrain(water_line=1.5,generate=True)
        elif symbol == key.Q :
            exit(0)
        elif symbol == key.ESCAPE:
            self.set_exclusive_mouse(False)

        elif symbol == key.O :
            self.press["light"] = 1
        elif symbol == key.P :
            self.press["light"] = -1


    def on_key_release(self, symbol, modifiers):
        """ Called when the player releases a key. See pyglet docs for key
        mappings.

        Parameters
        ----------
        symbol : int
            Number representing the key that was pressed.
        modifiers : int
            Number representing any modifying keys that were pressed.

        """
        if symbol == key.W:
            self.strafe[0] += 1
        elif symbol == key.S:
            self.strafe[0] -= 1
        elif symbol == key.A:
            self.strafe[1] += 1
        elif symbol == key.D:
            self.strafe[1] -= 1

        elif symbol == key.LEFT :
            self.kostka.input[0] = False
        elif symbol == key.RIGHT :
            self.kostka.input[1] = False

        elif symbol == key.O :
            self.press["light"] = 0
        elif symbol == key.P :
            self.press["light"] = 0
示例#4
0
class Game:
    clock = pygame.time.Clock()
    fps = 120

    def __init__(self, terrain_name):
        pygame.init()

        self.terrain = Terrain(terrain_name)
        self.window_size = [self.terrain.pixel_size[0] + 250, self.terrain.pixel_size[1] + 150]
        self.window = pygame.display.set_mode(self.window_size)

        self.init_content()


    def init_content(self):
        info_box = TextBox(200, 400, bgcolor=colors['white'], alpha=150)
        info_box.set_position([self.terrain.pixel_size[0] + 25, 250])
        info_box.add_default_text("Tower Defence\n\nPlace turrets on the map to protect your base from enemies. You gain money by winning rounds and killing enemies.", align="center")
        self.box_group = pygame.sprite.Group(info_box)

        cannon_button = button.TowerButton(CannonTower, self.terrain, info_box)
        artillery_button = button.TowerButton(ArtilleryTower, self.terrain, info_box)


        self.tower_buttons = GridGroup(pos=[self.terrain.pixel_size[0] + 25, 15], cols=3, rows=3, margin=10)
        self.tower_buttons.add(cannon_button, artillery_button)


        for _ in range(7):
            empty = button.Button(colors['white'], 60, 60)
            self.tower_buttons.add(empty)
            empty.lock()

        start_button = button.Button(colors['green'], 200, 90)
        start_button.set_position((self.terrain.pixel_size[0] + 25, 670))
        start_button.set_icon_text("Start", font_size=50)
        start_button.set_description("Start round 1", info_box)
        start_button.function = self.start_round

        self.description = info_box
        self.start_button = start_button
        self.buttons = pygame.sprite.Group(start_button)

    def start_round(self):
        pygame.time.set_timer(pygame.USEREVENT, 1000)
        self.start_button.lock()

    def mainloop(self):
        while True:

            mouse = pygame.mouse.get_pos()

            for event in pygame.event.get():
                self.tower_buttons.update(event)
                self.buttons.update(event)
                self.terrain.handle_event(event, mouse)
                self.handle_event(event)

            # Logic testing:
            self.terrain.update()

            # Draw everything:
            self.draw_everything()

            # Delay framerate and update display:
            self.clock.tick(self.fps)
            pygame.display.flip()


    def handle_event(self, event):
        if event.type == QUIT:
            pygame.quit()
            quit()
        elif event.type == USEREVENT:
            self.terrain.enemy_group.add(Boss(self.terrain))
        elif event.type == KEYDOWN:
            if event.key == K_r:
                self.terrain.static_tower_group.empty()
                self.terrain.enemy_group.empty()
            elif event.key == K_DELETE:
                get_active(self.terrain.static_tower_group).kill()

    def draw_everything(self):
        self.window.fill(colors['background'])
        self.terrain.draw(self.window)
        self.tower_buttons.draw(self.window)
        self.buttons.draw(self.window)
        self.box_group.draw(self.window)

        
        
示例#5
0
class GLWidget(QGLWidget):
    GL_MULTISAMPLE = 0x809D
    rot = 0.0
    lastMousePos = None

    maskCreated = pyqtSignal(np.ndarray)

    def __init__(self, parent):
        # OpenGL Widget setup
        f = QGLFormat()
        f.setSampleBuffers(True)
        f.setVersion(3,3)
        f.setProfile(QGLFormat.CoreProfile)
        QGLFormat.setDefaultFormat(f)

        if not QGLFormat.hasOpenGL():
            QMessageBox.information(None, "OpenGL samplebuffers",
                    "This system does not support OpenGL.")
            sys.exit(0)
        super(GLWidget, self).__init__(f, parent)
        self.setFocusPolicy(Qt.StrongFocus)
        self.list_ = []
        self.width = 640.0
        self.height = 480.0
        self.startTimer(40)
        self.setWindowTitle("Sample Buffers")
        self.fov = 60.0
        self.deltaTime = 0.0
        self.lastFrame = None
        self.sketching = False
        self.sketchType = 0
        self.sketchPoints = []


    def initializeGL(self):
        GL.glClearColor(0.50, 0.50, 0.50, 1.0)
        #GL.glEnable(GL.GL_ALPHA_TEST)
        #GL.glAlphaFunc(GL.GL_NOTEQUAL, 0.0)
        self.heightMap = HeightMap('textures/atacama_height2.png')
        self.projection = QMatrix4x4()
        self.projection.perspective(self.fov, self.width / self.height, 0.01, 10000)
        self.cameraPos = QVector3D(0.0, 1.0, 1.0)
        self.terrainPos = QVector3D(0.0, 0.0, 0.0)
        self.roverPos = QVector3D(0.0, 0.0, 0.0)
        print(GL.glGetString(GL.GL_VERSION))
        self.camera = Camera(self.cameraPos, self.heightMap)
        self.terrain = Terrain(self.terrainPos, self.heightMap)

        self.mask = np.zeros([1001,1001])
        self.terrain.updateRewards(self.mask)

        # self.rover = Rover(roverPos)

    def resizeGL(self, w, h):
        self.width = float(w)
        self.height = float(h)
        GL.glViewport(0, 0, w, h)
        self.projection = QMatrix4x4()
        self.projection.perspective(self.fov, (self.width / self.height), 0.01, 10000)


    def setRoverPosition(self, x, y):
        self.camera.setPosition(x-500.5,y-500.5)

    def paintGL(self):
        currentFrame = QTime.currentTime()
        if (self.lastFrame):
            self.deltaTime = self.lastFrame.msecsTo(currentFrame)
            self.lastFrame = currentFrame
        else:
            self.lastFrame = currentFrame
        GL.glClearColor(0.90, 0.90, 0.90, 1.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glEnable(GL.GL_BLEND)
        GL.glEnable(GLWidget.GL_MULTISAMPLE)


        self.view = self.camera.getViewMatrix(self.roverPos)
        self.terrain.draw(self.projection, self.view)

        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)

    def mousePressEvent(self, event):
        viewport = np.array(GL.glGetIntegerv(GL.GL_VIEWPORT))

        if(self.sketching):
            self.sketchPoints.append([event.x(), viewport[3] - event.y()])
        else:
            self.lastMousePos = event.pos()
            print("clicked")
            cursorX = event.x()
            cursorY = event.y()
            winX = float(cursorX)
            winY = float(viewport[3] - cursorY)

            # obtain Z position
            winZ = GL.glReadPixels(winX, winY, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT);

            winVector = QVector3D(winX, winY, winZ)
            print(winVector)

    def mouseMoveEvent(self, event):
        #print(event.pos())
        #print(self.lastMousePos)
        if(True):
            print(event.pos())
            viewport = np.array(GL.glGetIntegerv(GL.GL_VIEWPORT))

            if(self.sketching):
                self.sketchPoints.append([event.x(), viewport[3] - event.y()])
                #self.painter.drawPoint(event.pos())
                print("Testing mouse move")
            elif(self.lastMousePos is not None):
                print(event.pos())
                dx = event.x() - self.lastMousePos.x()
                dy = event.y() - self.lastMousePos.y()
                self.camera.processMouseMovement(dx,dy)
                self.lastMousePos = event.pos()
            elif(event.button() == Qt.MiddleButton):
                # Dont use this : doesnt work well with trackpads
                print("Middle")
            elif(event.button() == Qt.RightButton):
                print("Right")

    def mouseReleaseEvent(self, event):
        print("Mouse Released")
        if(self.sketching):
            # print(self.sketchPoints)
            self.createSketchMask()
            self.sketching = False

    def createSketchMask(self):
        # obtain Z position
        # pass
        pixels = []
        viewport = np.array(GL.glGetIntegerv(GL.GL_VIEWPORT))
        for point in self.sketchPoints:
            winZ = GL.glReadPixels(point[0], point[1], 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT);

            winVector = QVector3D(point[0], point[1], winZ)
            # print(winVector)
            object_coord = self.terrain.getObjectCoord(winVector, self.projection, self.view, viewport)
            j = round(1001 - 1001 * ((0.5 * object_coord[2]) + 0.5) )
            i = round( 1001 * ((0.5 * object_coord[0]) + 0.5) )
            pixels.append([i,j])
        pixelsNP = np.array([pixels])
        cv.drawContours(self.mask, pixelsNP, 0, [self.sketchType], -1)
        self.sketchPoints = []
        self.terrain.updateRewards(self.mask)
        self.maskCreated.emit(self.mask)

    def wheelEvent(self, event):
        self.camera.scroll((event.angleDelta().y()))

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_1:
            self.camera.setViewType(0)
        elif event.key() == Qt.Key_2:
            self.camera.setViewType(1)
        elif event.key() == Qt.Key_3:
            self.camera.setViewType(2)
        elif event.key() == Qt.Key_4:
            self.sketching = True
            self.sketchType = -1
        elif event.key() == Qt.Key_5:
            self.sketching = True
            self.sketchType = 0
        elif event.key() == Qt.Key_6:
            self.sketching = True
            self.sketchType = 1
        elif event.key() == Qt.Key_W:
            self.camera.processKeyboard('F', self.deltaTime)
        elif event.key() == Qt.Key_S:
            self.camera.processKeyboard('B', self.deltaTime)
        elif event.key() == Qt.Key_A:
            self.camera.processKeyboard('L', self.deltaTime)
        elif event.key() == Qt.Key_D:
            self.camera.processKeyboard('R', self.deltaTime)

    def timerEvent(self, event):
        self.update()

    def setRewards(self, mask):
        self.learnedRewards = mask
        self.terrain.updatelearnedRewards(self.learnedRewards)

    def setPath(self, mask):
        self.pathMask = mask
        self.terrain.updatePaths(self.pathMask)
示例#6
0
class Game(pyglet.event.EventDispatcher):
	def __init__(self):
		self.window = pyglet.window.Window(fullscreen=True)
		self.terrain = Terrain(self.window.width, self.window.height-100)
		self.players = [
			Player(name, self, i)
			for i, name in enumerate(sys.argv[1:])]
		self.moving = []
		
		# Setup events
		self.window.event(self.on_draw)
		Game.register_event_type('next_player')
		Game.register_event_type('start_moving')
		Game.register_event_type('stop_moving')
		Game.register_event_type('explosion')
		
		# Start the game.
		self.reset()
		
		# Run the f****r
		pyglet.app.run()
	
	def reset(self):
		self.terrain.reset()
		for p in self.players:
			p.reset()
		random.shuffle(self.players)
		
		for p in self.players:
			new_x = None
			while not new_x:
				new_x = int(random.uniform(20, self.window.width - 20))
				for other in self.players:
					if other != p and abs(other.pos[0] - new_x) < 50:
						new_x = None
						break
			p.pos = new_x, self.terrain.flatten(new_x)
		
		self.next_player()
	
	def next_round(self):
		for p in self.players:
			p.next_round()
		self.next_player()
	
	def next_player(self):
		live_players = list(filter(lambda p: p.alive, self.players))
		if len(live_players) < 2:
			for p in live_players:
				p.score += 10000
			self.reset()
			return
		
		for p in live_players:
			if not p.ready:
				p.take_turn()
				return
		self.moving = [
			Shot(p.pos, p.angle, p.power, p)
			for p in self.players
			if p.alive]
		pyglet.clock.schedule(self.move, 1/60)
	
	def move(self, *args, **kwargs):
		for s in self.moving:
			s.move(self)
	
	def explosion(self, x, y, r, player=None):
		self.terrain.explosion(x, y, r)
		for p in self.players:
			p.explosion(x, y, r, player)
	
	def stop_moving(self, thing):
		self.moving.remove(thing)
		if not self.moving:
			pyglet.clock.unschedule(self.move)
			self.next_round()
	
	def start_moving(self, thing):
		self.moving.append(thing)
		
	def on_draw(self):
		self.window.clear()
		self.terrain.draw(self.window.width, self.window.height-100, 100)
		for p in self.players:
			p.draw()
		for m in self.moving:
			m.draw(self.window.height-100)
class Robot(object):
    def __init__(self, maze_dim):
        """
        Used to set up attributes that the robot will use to learn and
        navigate the maze.
        """

        # Position-related attributes
        self.robot_pos = {'location': [0, 0], 'heading': 'up'}  # Current pos
        self.steps_first_round = 0
        self.steps_final_round = 0
        self.maze_dim = maze_dim
        self.maze_representation = None

        # Goal-related attributes
        center = maze_dim/2
        self.center_locations = [
            [center, center], [center - 1, center],
            [center, center - 1], [center - 1, center - 1]]
        self.reached_destination = False

        # For exploring state
        self.exploring = False
        self.steps_exploring = 0
        self.consecutive_explored_cells = 0

        # Initialize terrain
        self.terrain = Terrain(maze_dim)

        # Algorithm to use:
        self.algorithm = None

        if str(sys.argv[2]).lower() == 'ff':
            self.algorithm = FloodFill()
        elif str(sys.argv[2]).lower() == 'ar':
            self.algorithm = AlwaysRight()
        elif str(sys.argv[2]).lower() == 'mr':
            self.algorithm = ModifiedRight()
        else:
            raise ValueError(
                "Incorrect algorithm name. Options are: "
                "\n- 'ff': flood-fill"
                "\n- 'ar': always-right"
                "\n- 'mr': modified-right (prefers unvisited cells)"
            )

        # Explore after reaching center of the maze:
        if str(sys.argv[3]).lower() == 'true':
            self.explore_after_center = True
        elif str(sys.argv[3]).lower() == 'false':
            self.explore_after_center = False
        else:
            raise ValueError(
                "Incorrect explore value: Options are: "
                "\n- 'true': to keep exploring after reaching the center"
                "\n- 'false': to end run immediately after reaching the center"
            )

    def next_move(self, sensors):
        """
        Use this function to determine the next move the robot should make,
        based on the input from the sensors after its previous move. Sensor
        inputs are a list of three distances from the robot's left, front, and
        right-facing sensors, in that order.

        Outputs should be a tuple of two values. The first value indicates
        robot rotation (if any), as a number: 0 for no rotation, +90 for a
        90-degree rotation clockwise, and -90 for a 90-degree rotation
        counterclockwise. Other values will result in no rotation. The second
        value indicates robot movement, and the robot will attempt to move the
        number of indicated squares: a positive number indicates forwards
        movement, while a negative number indicates backwards movement. The
        robot may move a maximum of three units per turn. Any excess movement
        is ignored.

        If the robot wants to end a run (e.g. during the first training run in
        the maze) then returning the tuple ('Reset', 'Reset') will indicate to
        the tester to end the run and return the robot to the start.
        """

        # Store current location and direction
        x, y, heading = self.get_current_position()

        # Get walls for current location
        walls = self.get_walls_for_current_location(x, y, heading, sensors)

        # If we have reached the center of the maze
        if self.is_at_center_of_the_maze(x, y):

            # Move backwards
            rotation = 0
            movement = -1

            # Update terrain (visual representation)
            self.terrain.update(x, y, heading, walls, self.exploring)

            # State that we have reached destination
            self.reached_destination = True

            # Set flags to exploring
            self.exploring = True

        # Else, first update distances, then get next move
        else:

            # 1) Push current location to stack
            self.terrain.cells_to_check.append([x, y])

            # 2) Add current cell to stack of visited destinations
            if [x, y] not in self.terrain.visited_before_reaching_destination:
                self.terrain.visited_before_reaching_destination.append([x, y])

            # 4) Update terrain and distances
            self.terrain.update(x, y, heading, walls, self.exploring)

            # 4) Get next move
            rotation, movement = self.get_next_move(x, y, heading, sensors)

        self.update_location(rotation, movement)

        # If we have reached destination, reset values
        if rotation == 'Reset' and movement == 'Reset':
            self.reset_values()

        # If we are about to hit the goal in the second round
        if self.robot_pos['location'] in self.center_locations \
                and self.steps_final_round != 0:
            self.report_results()

        return rotation, movement

    # --------------------------------------------
    # LOCATION-RELATED
    # --------------------------------------------

    def reset_values(self):
        self.robot_pos = {'location': [0, 0], 'heading': 'up'}

    def get_current_position(self):
        heading = self.robot_pos['heading']
        location = self.robot_pos['location']
        x = location[0]
        y = location[1]
        return x, y, heading

    def is_at_starting_position(self, x, y):
        return x == 0 and y == 0

    def is_at_center_of_the_maze(self, x, y):
        return [x, y] in self.center_locations

    def is_at_a_dead_end(self, sensors):
        x, y, heading = self.get_current_position()
        adj_distances, adj_visited = \
            self.terrain.get_adj_info(x, y, heading, sensors, False)
        return sensors == [0, 0, 0] or adj_distances == list(MAX_DISTANCES)

    def get_walls_for_current_location(self, x, y, heading, sensors):

        if self.is_at_starting_position(x, y):
            walls = [1, 0, 1, 1]

        # If it had been visited before, just get those values
        elif self.terrain.grid[x][y].visited != '':
            walls = self.terrain.grid[x][y].get_total_walls()

        # Else, get current walls. Note that it can only have real walls
        # since the location has never been visited, and imaginary walls
        # are the result of dead ends that force the robot to the prev location
        else:
            # Placeholder
            walls = [0, 0, 0, 0]

            # Change sensor info to wall info
            walls_sensors = [1 if x == 0 else 0 for x in sensors]

            # Map walls to correct x and y coordinates
            for i in range(len(walls_sensors)):
                dir_sensor = dir_sensors[heading][i]
                index = wall_index[dir_sensor]
                walls[index] = walls_sensors[i]

            # Update missing wall index (the cell right behind the robot)
            index = wall_index[dir_reverse[heading]]
            walls[index] = 0

        return walls

    def get_new_direction(self, rotation):
        if rotation == -90:
            return dir_sensors[self.robot_pos['heading']][0]
        elif rotation == 90:
            return dir_sensors[self.robot_pos['heading']][2]
        else:
            return self.robot_pos['heading']

    def update_location(self, rotation, movement):

        if movement == 'Reset' or rotation == 'Reset':
            return

        else:
            movement = int(movement)

            # Perform rotation
            if rotation == -90:
                self.robot_pos['heading'] = \
                    dir_sensors[self.robot_pos['heading']][0]
            elif rotation == 90:
                self.robot_pos['heading'] = \
                    dir_sensors[self.robot_pos['heading']][2]

            # Advance
            if movement == -1:
                self.robot_pos['location'][0] -= \
                    dir_move[self.robot_pos['heading']][0]
                self.robot_pos['location'][1] -= \
                    dir_move[self.robot_pos['heading']][1]
            else:
                while movement > 0:
                    self.robot_pos['location'][0] += \
                        dir_move[self.robot_pos['heading']][0]
                    self.robot_pos['location'][1] += \
                        dir_move[self.robot_pos['heading']][1]
                    movement -= 1

    def number_of_walls(self, sensors):
        number_of_walls = 0
        for sensor in sensors:
            if sensor == 0:
                number_of_walls += 1
        return number_of_walls

    # --------------------------------------------
    # MOVEMENT-RELATED
    # --------------------------------------------

    def get_next_move(self, x, y, heading, sensors):

        if self.reached_destination and self.exploring:
            rotation, movement = self.explore(x, y, heading, sensors)
            self.steps_exploring += 1

        elif not self.reached_destination and not self.exploring:

            if self.algorithm.name == 'flood-fill' and self.is_at_a_dead_end(sensors):
                rotation, movement = self.deal_with_dead_end(x, y, heading)

            else:

                adj_distances, adj_visited = self.terrain.get_adj_info(
                    x, y, heading, sensors)
                valid_index = self.algorithm.get_valid_index(adj_distances, adj_visited)
                rotation, movement = self.convert_from_index(valid_index)

            self.steps_first_round += 1

        else:
            # Final round (optimized movements)
            if self.steps_final_round == 0:
                print('******* FINAL REPORT *******')
                self.terrain.draw()
            rotation, movement = self.final_round(x, y, heading, sensors)
            self.steps_final_round += 1

        return rotation, movement

    def get_valid_index(self, x, y, heading, sensors, exploring):

        if not exploring:

            # 1) Get adjacent distances from sensors
            adj_distances, adj_visited = self.terrain.get_adj_info(
                x, y, heading, sensors)

            # Get min index (guaranteed to not be a wall)
            valid_index = adj_distances.index(min(adj_distances))

            # Prefer unvisited cells
            possible_distance = WALL_VALUE
            best_index = WALL_VALUE
            for i, dist in enumerate(adj_distances):
                if dist != WALL_VALUE and adj_visited[i] is '':
                    if dist <= possible_distance:
                        best_index = i
                        if best_index == 1:
                            break

            if best_index != WALL_VALUE:
                valid_index = best_index

        else:

            # 1) Get adjacent distances from sensors
            adj_distances, adj_visited = self.terrain.get_adj_info(
                x, y, heading, sensors)

            # Convert WALL_VALUES to -1 (robot will follow max distance)
            adj_distances = [-1 if dist == WALL_VALUE else dist for dist in
                             adj_distances]

            # Get max index (guaranteed to not be a wall)
            valid_index = None

            # Prefer cells that have not been visited
            for i, dist in enumerate(adj_distances):
                if dist != -1 and adj_visited[i] is '':
                    self.consecutive_explored_cells = 0
                    valid_index = i
                    break

            if valid_index is None:
                self.consecutive_explored_cells += 1
                possible_candidate = None
                for i, dist in enumerate(adj_distances):
                    if dist != -1 and adj_visited[i] is '*':
                        if possible_candidate is None:
                            possible_candidate = i
                        else:
                            a = adj_distances[possible_candidate]
                            b = adj_distances[i]
                            if b > a:
                                possible_candidate = i

                valid_index = possible_candidate

            if valid_index is None:
                possible_candidate = None
                for i, dist in enumerate(adj_distances):
                    if dist != -1 and adj_visited[i] is 'e':
                        if possible_candidate is None:
                            possible_candidate = i
                        else:
                            a = adj_distances[possible_candidate]
                            b = adj_distances[i]
                            if b > a:
                                possible_candidate = i

                valid_index = possible_candidate

        return valid_index

    def explore(self, x, y, heading, sensors):

        if self.should_end_exploring(x, y) or not self.explore_after_center:
            rotation = 'Reset'
            movement = 'Reset'
            self.exploring = False
            self.terrain.set_imaginary_walls_for_unvisited_cells()
            self.terrain.update_distances(last_update=True)

        else:

            # If we reach a dead end:
            if self.is_at_a_dead_end(sensors):
                rotation, movement = self.deal_with_dead_end(x, y, heading)

            else:
                valid_index = self.get_valid_index(x, y, heading, sensors, True)
                if valid_index is not None:
                    rotation, movement = self.convert_from_index(valid_index)
                else:
                    rotation, movement = 'Reset', 'Reset'

        return rotation, movement

    def convert_from_index(self, index):
        # Move Left
        if index == 0:
            rotation = -90
            movement = 1
        # Move Up
        elif index == 1:
            rotation = 0
            movement = 1
        # Move Right
        elif index == 2:
            rotation = 90
            movement = 1
        # Minimum distance is behind, so just rotate clockwise
        else:
            rotation = 90
            movement = 0

        return rotation, movement

    def deal_with_dead_end(self, x, y, heading):
        # 1) Move back one step
        rotation = 0
        movement = -1

        # 2) Get reference to cell
        cell = self.terrain.grid[x][y]
        # 3) Place imaginary wall behind the robot before exiting location
        reverse_direction = dir_reverse[heading]
        index = self.terrain.get_index_of_wall(reverse_direction)
        cell.imaginary_walls[index] = 1

        # 4) Change the value of visited to signify dead end
        cell.visited = 'x'
        cell.distance = WALL_VALUE

        # 5) Update imaginary walls and distances
        self.terrain.update_imaginary_walls(x, y, cell.imaginary_walls)

        return rotation, movement

    def should_end_exploring(self, x, y):
        """
        The robot should end exploring in all these cases:
        - It has already explored more than 90% of the cells
        - It has already taken 30 steps (in the exploration phase)
        - It has reached the center of the maze (again)
        - It has reached the starting location (again)
        """

        # Check for % of cells covered
        if self.terrain.get_percentage_of_maze_explored() > 80:
            return True

        if self.consecutive_explored_cells >= 3:
            return True

        # Check for number of steps
        if self.steps_exploring > 15:
            return True

        # Check for center of the maze:
        if self.is_at_center_of_the_maze(x, y):
            return True

        if self.is_at_starting_position(x, y):
            return True

        return False

    def final_round(self, x, y, heading, sensors):
        """
        Returns the correct rotation and maximum numbers of steps that
         the robot can take to optimize the score while staying on track
        """

        rotation = None
        movement = None
        current_distance = self.terrain.grid[x][y].distance

        adj_distances, adj_visited = \
            self.terrain.get_adj_info(
                x, y, heading, sensors, False)

        # Change sensor info to max allowed moves, when it applies
        sensors = [3 if step > 3 else step for step in sensors]

        for i, steps in enumerate(sensors):

            # If we found a movement, exit and apply it
            if movement is not None:
                break

            # Otherwise, iterate through steps to see if one matches with the
            # next correct and logical distance for that number of steps
            elif self.is_a_possible_move(adj_distances, adj_visited, i):
                for idx in range(steps):
                    step = steps - idx
                    rotation = rotations[str(i)]
                    new_direction = self.get_new_direction(rotation)
                    furthest_distance = self.terrain.get_distance(
                        x, y, new_direction, step)
                    if furthest_distance == current_distance - step:
                        movement = step
                        break

        return rotation, movement

    def is_a_possible_move(self, adj_distances, adj_visited, i):
        """
        Distances are valid if they are not walls, unvisited, or dead ends.
        """
        return (adj_visited[i] is not ''
                and adj_visited[i] is not 'x'
                and adj_distances[i] is not WALL_VALUE)

    def report_results(self):
        distance = self.terrain.grid[0][0].distance
        percentage = self.terrain.get_percentage_of_maze_explored()
        first_round = self.steps_first_round + self.steps_exploring
        final_round = self.steps_final_round
        print('ALGORITHM USED: {}'.format(self.algorithm.name.upper()))
        print('EXPLORING AFTER CENTER: {}'.format(self.explore_after_center))
        print('NUMBER OF MOVES FIRST ROUND: {}'.format(first_round))
        print('PERCENTAGE OF MAZE EXPLORED: {}%'.format(percentage))
        print('DISTANCE TO CENTER: {}'.format(distance))
        print('NUMBER OF MOVES FINAL ROUND: {}'.format(final_round))
        print('********************************')
示例#8
0
文件: main.py 项目: kad99kev/PyBoxCar
class MainScreen(arcade.Window):
    '''
    Main application class.
    '''
    def __init__(self, width, height, title):
        super().__init__(width, height, title)

        arcade.set_background_color(arcade.color.WHITE_SMOKE)

    def setup(self):
        '''
        Setting up the environment.
        '''
        # Setting up space.
        self.space = pymunk.Space()
        self.space.gravity = GRAVITY
        self.space.sleep_time_threshold = 1

        # Creating cars.
        self.cars = []
        for _ in range(NUM_CARS):
            self.cars.append(BoxCar(self.space))

        # Setting up terrain and checkpoints.
        self.terrain = Terrain(self.space)
        self.checkpoints = self.terrain.get_checkpoints()

        # Setting up extra UI elements.
        self.goal = arcade.create_line(self.checkpoints[-1].x - 40,
                                       self.checkpoints[-1].y,
                                       self.checkpoints[-1].x - 40,
                                       self.checkpoints[-1].y + 50,
                                       arcade.color.GREEN, 2)
        self.generation_number = 1
        self.best_score = 0
        self.plot_history = []
        self.score_history = []
        self.score_list = arcade.ShapeElementList()

    def on_draw(self):
        '''
        Render the screen.
        '''

        arcade.start_render()

        self.goal.draw()

        self.show_status()

        self.terrain.draw()

        for car in self.cars:
            car.draw()

    def on_update(self, delta_time):
        '''
        Update the simulation.
        '''

        self.space.step(DT)

        # To check if all cars in the current generation are alive.

        all_dead = True
        for car in self.cars:
            alive = car.update_lifespan(self.checkpoints)
            if alive:
                all_dead = False
                if self.best_score < car.get_checkpoint_index():
                    self.best_score = car.get_checkpoint_index()

        if all_dead:
            self.new_generation()

    def new_generation(self):
        '''
        Generate a new generation of cars.
        '''

        gene_scores = []

        for car in self.cars:
            g_s = car.get_chromosome_and_score()
            gene_scores.append(g_s)
        new_genes = evolve(gene_scores)

        constraints = self.space.constraints
        for c in constraints:
            self.space.remove(c)
        for car in self.cars:
            self.space.remove(car.chassis.body, car.chassis.shape)
            for wheel in car.wheels:
                self.space.remove(wheel.body, wheel.shape)

        self.cars = []
        for gene in new_genes:
            self.cars.append(BoxCar(self.space, gene))

        self.plot_history.append(self.best_score)
        plt.clf()
        plt.plot(self.plot_history)
        plt.xlabel('Number of Generations')
        plt.ylabel('Best Score per Generation')
        plt.draw()
        plt.show(block=False)

        self.score_history.append({
            'gen': self.generation_number,
            'score': self.best_score
        })
        self.score_history = sorted(self.score_history,
                                    key=lambda x: x['score'],
                                    reverse=True)[:25]

        self.best_score = 0
        self.generation_number += 1

    def show_status(self):
        '''
        Show the current generation and history stats.
        '''

        score = f"Current Generation: {self.generation_number}\nBest Car Info | Score: {self.best_score}"
        arcade.draw_text(score, 50, 50, arcade.color.RED, anchor_y='top')

        arcade.draw_text('Top 25 Scores',
                         1100,
                         780,
                         arcade.color.DARK_BLUE,
                         anchor_x='center',
                         anchor_y='top')

        for i, score in enumerate(self.score_history):
            arcade.draw_text(
                f"Generation: {score['gen']} | Score: {score['score']}\n",
                1120,
                760 - i * 30,
                arcade.color.DARK_ELECTRIC_BLUE,
                anchor_x='center',
                anchor_y='top')
示例#9
0
class GLWidget(QGLWidget):
    GL_MULTISAMPLE = 0x809D
    rot = 0.0
    lastMousePos = None

    maskCreated = pyqtSignal(np.ndarray)

    def __init__(self, parent):
        # OpenGL Widget setup
        f = QGLFormat()
        f.setSampleBuffers(True)
        f.setVersion(3, 3)
        f.setProfile(QGLFormat.CoreProfile)
        QGLFormat.setDefaultFormat(f)

        if not QGLFormat.hasOpenGL():
            QMessageBox.information(None, "OpenGL samplebuffers",
                                    "This system does not support OpenGL.")
            sys.exit(0)
        super(GLWidget, self).__init__(f, parent)
        self.setFocusPolicy(Qt.StrongFocus)
        self.list_ = []
        self.width = 640.0
        self.height = 480.0
        self.startTimer(40)
        self.setWindowTitle("Sample Buffers")
        self.fov = 60.0
        self.deltaTime = 0.0
        self.lastFrame = None
        self.sketching = False
        self.sketchType = 0
        self.sketchPoints = []

        # RoverCAM State Variables
        self.captureMode = False
        self.captured = False

    def initializeGL(self):
        GL.glClearColor(0.50, 0.50, 0.50, 1.0)

        self.mode = 2

        self.xN = 200
        self.yN = 200
        self.yawN = 0

        self.pathX = np.linspace(450, 550, 100)
        self.pathNode = 0
        self.renderMode = 0

        self.heightMap = HeightMap('textures/atacama_height2.png')
        self.projection = QMatrix4x4()
        self.projection.perspective(self.fov, self.width / self.height, 0.01,
                                    10000)
        self.cameraPos = QVector3D(0.0, 1.0, 1.0)
        self.terrainPos = QVector3D(0.0, 0.0, 0.0)
        self.roverPos = QVector3D(0.0, 0.0, 0.0)
        print(GL.glGetString(GL.GL_VERSION))
        self.camera = Camera(self.cameraPos, self.heightMap)
        self.camera.setProjection(self.fov, self.width, self.height, 0.01,
                                  1000)
        self.roverCamera = Camera(self.cameraPos, self.heightMap)
        self.roverCamera.setProjection(self.fov, self.width, self.height, 0.01,
                                       1000)

        self.terrain = Terrain(self.terrainPos, self.heightMap)

        self.mask = np.zeros([1001, 1001])
        self.terrain.updateRewards(self.mask)

        # set up frame buffer
        self.fbo = GL.glGenFramebuffers(1)
        GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, self.fbo)
        # Attachments for frame buffer : Texture
        self.Frametexture = GL.glGenTextures(1)
        GL.glBindTexture(GL.GL_TEXTURE_2D, self.Frametexture)
        GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, 640, 480, 0, GL.GL_RGB,
                        GL.GL_UNSIGNED_BYTE, None)
        GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
                           GL.GL_LINEAR)
        GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
                           GL.GL_LINEAR)

        GL.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0,
                                  GL.GL_TEXTURE_2D, self.Frametexture, 0)

        self.rbo = GL.glGenRenderbuffers(1)
        GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, self.rbo)
        GL.glRenderbufferStorage(GL.GL_RENDERBUFFER, GL.GL_DEPTH24_STENCIL8,
                                 640, 480)
        GL.glBindRenderbuffer(GL.GL_RENDERBUFFER, 0)

        GL.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
                                     GL.GL_DEPTH_STENCIL_ATTACHMENT,
                                     GL.GL_RENDERBUFFER, self.rbo)
        if (GL.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER) !=
                GL.GL_FRAMEBUFFER_COMPLETE):
            print("Framebuffer not complete")
        GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0)
        GL.glBindTexture(GL.GL_TEXTURE_2D, 0)

        # self.rover = Rover(roverPos)

    def resizeGL(self, w, h):
        self.width = float(w)
        self.height = float(h)
        GL.glViewport(0, 0, w, h)
        self.projection = QMatrix4x4()
        self.projection.perspective(self.fov, (self.width / self.height), 0.01,
                                    10000)
        self.camera.setProjection(self.fov, self.width, self.height, 0.01,
                                  1000)

    def paintGL(self):
        if self.mode == 0:
            self.simplePaint()
        elif self.mode == 1:
            self.saveat()
            self.mode = 0
        elif self.mode == 2:
            self.createDataset()
        elif self.mode == 3:
            self.renderMode = 1
            self.createDataset()

    def simplePaint(self):
        GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0)
        currentFrame = QTime.currentTime()
        if (self.lastFrame):
            self.deltaTime = self.lastFrame.msecsTo(currentFrame)
            self.lastFrame = currentFrame
        else:
            self.lastFrame = currentFrame
        GL.glClearColor(0.90, 0.90, 0.90, 1.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glEnable(GLWidget.GL_MULTISAMPLE)
        self.terrain.draw(self.camera, self.renderMode)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)

    def saveat(self):
        image = self.setCameraPosition(self.pathX[self.pathNode],
                                       ((2 * self.pathX[self.pathNode]) - 345),
                                       0, -20)
        self.pathNode = self.pathNode + 1
        if self.pathNode > 99:
            self.pathNode = 0

    def createDataset(self):

        image = self.setCameraPosition(self.xN, self.yN, self.yawN, -20)
        imageName = "ima" + str(self.xN) + "_" + str(self.yN) + '_' + str(
            self.yawN) + ".jpeg"
        cv.imwrite('dataset/' + imageName, cv.flip(image, 0))
        self.yN = self.yN + 1
        if self.yN > 400:
            self.yN = 200
            self.xN = self.xN + 1

        if self.xN > 400:
            self.xN = 200
            self.mode = 0
        self.yawN = self.yawN + 45

    def setCameraPosition(self, x, y, yaw, pitch):
        self.roverCamera.setPosition(x - 500.5, y - 500.5)
        self.roverCamera.setYaw(yaw)
        self.roverCamera.setPitch(pitch)
        GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, self.fbo)
        GL.glClearColor(0.52, 0.80, 0.92, 1.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glEnable(GLWidget.GL_MULTISAMPLE)
        self.terrain.draw(self.roverCamera, self.renderMode)
        GL.glBindTexture(GL.GL_TEXTURE_2D, self.Frametexture)

        abc = GL.glGetTexImage(GL.GL_TEXTURE_2D, 0, GL.GL_BGR,
                               GL.GL_UNSIGNED_BYTE)
        # self.cde = int.from_bytes(self.abc, byteorder='big')
        image = np.reshape(np.fromstring(abc, dtype=np.uint8), (480, 640, 3))
        # cv.imwrite('framebuffer.jpeg', cv.flip(self.image, 0))
        return image

    def mousePressEvent(self, event):
        self.mode = 1
        viewport = np.array(GL.glGetIntegerv(GL.GL_VIEWPORT))
        # self.createDataset()
        if (self.sketching):
            self.sketchPoints.append([event.x(), viewport[3] - event.y()])
        else:
            self.lastMousePos = event.pos()
            print("clicked")
            cursorX = event.x()
            cursorY = event.y()
            winX = float(cursorX)
            winY = float(viewport[3] - cursorY)

            # obtain Z position
            winZ = GL.glReadPixels(winX, winY, 1, 1, GL.GL_DEPTH_COMPONENT,
                                   GL.GL_FLOAT)

            winVector = QVector3D(winX, winY, winZ)
            print(winVector)
        self.paintGL()

    def mouseMoveEvent(self, event):
        # print(event.pos())

        if (event.button() == Qt.LeftButton):
            viewport = np.array(GL.glGetIntegerv(GL.GL_VIEWPORT))

            if (self.sketching):
                self.sketchPoints.append([event.x(), viewport[3] - event.y()])
                # self.painter.drawPoint(event.pos())
            elif (self.lastMousePos is not None):
                dx = event.x() - self.lastMousePos.x()
                dy = event.y() - self.lastMousePos.y()
                self.camera.processMouseMovement(dx, dy)
                self.lastMousePos = event.pos()
            elif (event.button() == Qt.MiddleButton):
                # Dont use this : doesnt work well with trackpads
                print("Middle")
            elif (event.button() == Qt.RightButton):
                print("Right")

    def mouseReleaseEvent(self, event):
        print("Mouse Released")
        if (self.sketching):
            # print(self.sketchPoints)
            self.createSketchMask()
            self.sketching = False

    def createSketchMask(self):
        # obtain Z position
        # pass
        pixels = []
        viewport = np.array(GL.glGetIntegerv(GL.GL_VIEWPORT))
        for point in self.sketchPoints:
            winZ = GL.glReadPixels(point[0], point[1], 1, 1,
                                   GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT)

            winVector = QVector3D(point[0], point[1], winZ)
            # print(winVector)
            object_coord = self.terrain.getObjectCoord(winVector,
                                                       self.projection,
                                                       self.view, viewport)
            j = round(1001 - 1001 * ((0.5 * object_coord[2]) + 0.5))
            i = round(1001 * ((0.5 * object_coord[0]) + 0.5))
            pixels.append([i, j])
        pixelsNP = np.array([pixels])
        cv.drawContours(self.mask, pixelsNP, 0, [self.sketchType], -1)
        self.sketchPoints = []
        self.terrain.updateRewards(self.mask)
        self.maskCreated.emit(self.mask)

    def wheelEvent(self, event):
        self.camera.scroll((event.angleDelta().y()))

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_1:
            self.camera.setViewType(0)
        elif event.key() == Qt.Key_2:
            self.camera.setViewType(1)
        elif event.key() == Qt.Key_3:
            self.camera.setViewType(2)
        elif event.key() == Qt.Key_4:
            self.sketching = True
            self.sketchType = -1
        elif event.key() == Qt.Key_5:
            self.sketching = True
            self.sketchType = 0
        elif event.key() == Qt.Key_6:
            self.sketching = True
            self.sketchType = 1

        elif event.key() == Qt.Key_G:
            self.renderMode = 1

        elif event.key() == Qt.Key_H:
            self.renderMode = 0

        elif event.key() == Qt.Key_W:
            self.camera.processKeyboard('F', self.deltaTime)
        elif event.key() == Qt.Key_S:
            self.camera.processKeyboard('B', self.deltaTime)
        elif event.key() == Qt.Key_A:
            self.camera.processKeyboard('L', self.deltaTime)
        elif event.key() == Qt.Key_D:
            self.camera.processKeyboard('R', self.deltaTime)

    def timerEvent(self, event):
        self.update()

    def setRewards(self, mask):
        self.learnedRewards = mask
        self.terrain.updatelearnedRewards(self.learnedRewards)

    def setPath(self, mask):
        self.pathMask = mask
        self.terrain.updatePaths(self.pathMask)
示例#10
0
class Game(Scene):
    """
    This is the game class, this is the most important scene, and keeps track of the whole game
    """
    def __init__(self):
        """ Initializes the game scene """
        self.mainmenu = None
        self.winscreen = None
        self.initEvents()
        self.initTerrain()
        self.initTeams()

        self.createGameObjects()

        self.startNewGame()

    def initEvents(self):
        """ Initializes the eventreader """
        SceneManager().registerEventReader(self.do_action)

    def do_action(self, event):
        """
        Check the events, and do something when needed
        @param event: The event
        """
        
        # check events
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                for snail in TurnManager().currentTeam.orderedSnailList:
                    if snail.hasTurn:
                        snail.shoot()
            if event.key == pygame.K_ESCAPE:
                SceneManager().setScene(self.mainmenu)
    def clean(self):
        """ Clean everything up, so that application doesn't crash """
        self.turnManager.stopTimer()
        SceneManager().unregisterEventReader(self.do_action)

    def initTeams(self):
        """ Initializes the team """
        self.teams = []
        self.teamsAlive = 0

    def initTerrain(self):
        """ Initializes the terrain """
        self.terrain = Terrain()

    def createGameObjects(self):
        """ Create the terrain """
        self.terrain.create(15)

    def addTeam(self, name, numberOfSnails, gravity_direction):
        """
        Add a team to the game
        @param name: The name of the team
        @param numberOfSnails: The amount of snails the team has
        @param gravity_direction: The gravity direction of the team
        """
        team = Team(name)
        team.setGravity(gravity_direction)
        team.addSnails(numberOfSnails)
        team.setTeamImage((gravity_direction+1))
        self.teams.append(team)
        
    def startNewGame(self):
        """ Start a new game """
        for i in range(0, Settings.GAME_PLAYERS):
            self.addTeam('team '+str(i+1), Settings.GAME_SNAILS, i)
        self.turnManager = TurnManager()
        self.turnManager.setTeams(self.teams)

        self.gamemode = GameModes.GAME_PLACING_SNAILS

    def stopGame(self):
        """ Stop the game """
        self.turnManager.timer.cancel()
        teamColors = {1:'green', 2:'red', 3:'yellow', 4:'blue'}
        livingTeamColor = str(teamColors[self.teams[0].colorIndex])
        SceneManager().setScene(WinScreen(self.mainmenu, livingTeamColor))
        #SceneManager().scene = self.mainmenu

    def update(self, input):
        """
        Update the game
        @param input: The input class
        """
        self.terrain.update()
        self.updateTeams(input)

        self.updateGameMode()

    def updateTeams(self, input):
        """
        Update every team
        @param input: The input class
        """
        self.teamsAlive = 0
        for team in self.teams:
            team.update(input, self.terrain)
            self.teamsAlive += 1

    def updateGameMode(self):
        """ Update the gamemodes """
        if self.gamemode == GameModes.GAME_PLACING_SNAILS:
            for team in self.teams:
                for snail in team.sprites():
                    if snail.isPlaced == False:
                        return
            self.turnManager.startTimer()
            self.gamemode = GameModes.GAME_PLAYING
        if self.gamemode == GameModes.GAME_PLAYING:
            if self.teamsAlive <= 1:
                self.stopGame()

    def draw(self, surface):
        """
        Draw the game on a surface
        @param surface: The surface the game should be drawed on
        """
        self.terrain.draw(surface)
        for team in self.teams:
            team.draw(surface)

        #self.bullets.draw(surface)
        if self.gamemode == GameModes.GAME_PLAYING:
            self.turnManager.draw(surface)
示例#11
0
class Game:
    def __init__(self, screen: pygame.Surface):
        global current_game
        current_game = self
        self.screen = screen

        spritesheet = SpriteSheet('./assets/sprites.png')
        self.life_image = pygame.transform.scale(
            spritesheet.image_at((423, 345, 16, 8), color_key=-1), (64, 32))
        self.checkpoint_image = pygame.transform.scale(
            spritesheet.image_at((389, 335, 8, 8), color_key=-1), (32, 32))

        self.simplex = OpenSimplex()
        self.font = pygame.font.Font('freesansbold.ttf', 24)
        self.next_hole = self.screen.get_width(
        ) + random.random() * HOLE_SPACE_VAR
        self.holes = []
        self.checkpoint = 0
        self.checkpoint_score = 0
        self.lives = 3
        self.score = 0
        self.highest_score = 0

        self.terrain = Terrain(screen, MARTIAN_BROWN, self.terrain_point)
        self.all_sprites = pygame.sprite.Group()

        self.player = Player(START_LOCATION, 0)
        self.all_sprites.add(self.player)

    def tick(self):
        if not self.player.dead:
            self.generate_holes()
            self.terrain.move(SCROLL_SPEED)
            self.score += 1
            if self.score > self.highest_score:
                self.highest_score = self.score

            if self.player_collide_with_hole():
                self.explode()

            if self.terrain.x_pos >= self.checkpoint + CHECKPOINT_DISTANCE:
                self.checkpoint += CHECKPOINT_DISTANCE
                self.checkpoint_score = self.score
                self.remove_holes_before_checkpoint()

        self.all_sprites.update()

    def draw(self):
        self.screen.fill(pygame.Color(0, 0, 0))
        self.terrain.draw()
        self.draw_checkpoints()
        self.all_sprites.draw(self.screen)
        self.draw_hud()

    def explode(self):
        self.all_sprites.remove(self.player)
        self.player.dead = True
        explosion = Explosion(self.player.rect[0] - WHEEL_SIZE / 2,
                              self.player.rect[1], self.take_damage)
        self.all_sprites.add(explosion)

    def take_damage(self, explosion):
        self.all_sprites.remove(explosion)
        if self.lives > 0:
            self.goto_checkpoint()
            self.lives -= 1
        else:
            gameover = GameOver(self.screen.get_width() * 0.2,
                                self.screen.get_height() * 0.2,
                                int(self.screen.get_width() * 0.6),
                                int(self.screen.get_height() * 0.6),
                                self.highest_score, self.reset)
            self.all_sprites.add(gameover)

    def player_collide_with_hole(self):
        if not self.player.on_ground:
            return False
        for hole in self.holes:
            player_x = self.player.x_pos + ROVER_SIZE / 2
            hole_x = hole - self.terrain.x_pos
            if hole_x < player_x and player_x - 50 < hole_x + HOLE_WIDTH:
                return True
        return False

    def draw_checkpoints(self):
        next_checkpoint = CHECKPOINT_DISTANCE - self.terrain.x_pos % CHECKPOINT_DISTANCE - 32
        self.screen.blit(self.checkpoint_image,
                         (next_checkpoint, self.screen.get_height() - 100))

    def draw_hud(self):
        padding = 10

        score_text = self.font.render(f'Score: {self.score}', True, WHITE)
        self.screen.blit(score_text, (padding, padding, score_text.get_width(),
                                      score_text.get_height()))

        life_width, life_height = self.life_image.get_size()
        for i in range(self.lives):
            x = self.screen.get_width() - (padding + life_width) * (i + 1)
            y = padding
            self.screen.blit(self.life_image, (x, y, life_width, life_height))

    def generate_holes(self):
        end_x_pos = self.terrain.get_end_pos()
        if end_x_pos > self.next_hole:
            self.holes.append(self.next_hole)
            self.next_hole = self.next_hole + random.random(
            ) * HOLE_SPACE_VAR + HOLE_SPACE_MIN
            next_checkpoint = self.checkpoint + CHECKPOINT_DISTANCE
            if (self.next_hole + HOLE_WIDTH > next_checkpoint - HOLE_SPACE_MIN
                    and self.next_hole < next_checkpoint + HOLE_SPACE_MIN):
                self.next_hole = next_checkpoint + CHECKPOINT_SAFE_SPACE

    def terrain_point(self, x):
        y = 200
        for i in range(1, 5):
            y += self.simplex.noise2d(x / (10 * i**3), i * 100) * 2**i * 3
        new_hole = next(
            (hole for hole in self.holes if hole < x < hole + HOLE_WIDTH),
            None)
        if new_hole:
            x_root = HOLE_WIDTH / 2
            stretch = HOLE_DEPTH / x_root**2
            x_offset = x - new_hole - x_root
            y += stretch * (x_offset + x_root) * (x_offset - x_root)
        return y

    def remove_holes_before_checkpoint(self):
        self.holes = [hole for hole in self.holes if hole > self.checkpoint]

    def goto_checkpoint(self):
        self.score = self.checkpoint_score
        self.player.x_pos = START_LOCATION
        self.terrain.goto(self.checkpoint)
        self.all_sprites.add(self.player)
        self.player.dead = False

    def reset(self, gameover):
        self.all_sprites.remove(gameover)
        self.lives = 3
        self.score = 0
        self.highest_score = 0
        self.next_hole = self.screen.get_width(
        ) + random.random() * HOLE_SPACE_VAR
        self.holes = []
        self.terrain.goto(0)
        self.player.x_pos = START_LOCATION
        self.all_sprites.add(self.player)
        self.player.dead = False