예제 #1
0
 def __init__(self, size):
     os.environ["SDL_VIDEO_CENTERED"] = "1"
     pygame.init()
     self.size = size
     self.screen = pygame.display.set_mode(self.size)
     self.surf = pygame.Surface(self.size)
     self.clock = pygame.time.Clock()
     self.running = True
     self.stage = 1
     self.ray1 = Raycasting((200, 320), (500, 50))
     self.ray2 = Raycasting((200, 320), (200, 50))
     self.ray3 = Raycasting((200, 320), (300, 50))
     self.make_wall(10)
예제 #2
0
 def look_around(self, pos, dist):
     ray = Ray(pos, (1,1))
     col_sphere = ray.checklength(self.mob.collision.current_quad)
     if col_sphere < 80:
         westpoint = (pos[0] - dist, pos[1])
         west = self._raycast(pos, westpoint)
         eastpoint = (pos[0] + dist, pos[1])
         east = self._raycast(pos, eastpoint)
         southpoint = (pos[0], pos[1] + dist)
         south = self._raycast(pos, southpoint)
         northpoint = (pos[0], pos[1] - dist)
         north = self._raycast(pos, northpoint)
         col_sphere = False
         return {"west":west, "east":east, "south":south, "north":north}
     else:
         return {}
예제 #3
0
    def __init__(self, size):
        os.environ["SDL_VIDEO_CENTERED"] = "1"
        pygame.init()
        self.size = size
        self.screen = pygame.display.set_mode(self.size)
        self.surf = pygame.Surface(self.size)
        self.clock = pygame.time.Clock()
        self.myfont = pygame.font.SysFont("arial", 20)
        self.text1 = self.myfont.render("Press 1, 2 or 3 to pick a Ray", True, (0,0,0))
        self.text2 = self.myfont.render("Left Mouse Button for point A", True, (0,0,0))
        self.text3 = self.myfont.render("Right Mouse Button for point B", True, (0,0,0))
        self.txt1_rect = pygame.Rect(50, 10, 20, 20)
        self.txt2_rect = pygame.Rect(50, 30, 20, 20)
        self.txt3_rect = pygame.Rect(50, 50, 20, 20)

        self.running = True
        self.stage = 1
        self.ray1 = Raycasting((200, 320), (500, 50))
        self.ray2 = Raycasting((200, 320), (200, 50))
        self.ray3 = Raycasting((200, 320), (300, 50))

        self.make_wall(10) # Set the Number to any amount of tiles you want in the wall
예제 #4
0
    def __init__(self, level, windowSize, totalRays, fovDegrees, targetFps):
        self.level = level
        self.windowSize = windowSize
        self.fovDegrees = fovDegrees
        self.targetFps = targetFps

        self.moveSpeed = NORMALIZED_MOVE * (60 / targetFps)
        self.turnSpeed = NORMALIZED_TURN * (60 / targetFps) * (totalRays / 600)
        self.cataclysmSpeed = NORMALIZED_CATACLYSM * 0.00001 * (60 / targetFps)

        self.raycasting = None
        self.screen = None
        self.font = None
        self.minimap = None
        self.fovRays = None
        self.pixelsPerRay = None
        self.distanceToProjection = None
        self.player = None
        self.winScreen = None

        # Initialize raycasting logic
        self.raycasting = Raycasting(totalRays, BLOCK_SIZE, self.level)

        # Initialize pygame
        pygame.init()
        pygame.display.set_caption("Raycasting labyrint")
        self.screen = pygame.display.set_mode(self.windowSize)

        # Prepare font rendering
        pygame.font.init()
        self.font = pygame.font.SysFont("Sans Serif", 30)

        # Prepare minimap
        minimapSize = self.level.get_size() * BLOCK_SIZE // MINIMAP_SIZE_DIV
        self.minimap = pygame.Surface((minimapSize.x, minimapSize.y))

        # Compute fov related stuff
        self.fovRays = self.raycasting.degrees_to_ray_number(self.fovDegrees)
        self.pixelsPerRay = windowSize[0] // (totalRays //
                                              (360 // self.fovDegrees))

        # Compute distance between player and the projection plane (also fov stuff)
        self.distanceToProjection = int(
            (PROJECTION_WIDTH) / (tan(radians(self.fovDegrees / 2))))

        # Prepare fisheye correction
        self.fisheyeCoefficients = self.raycasting.fisheye_coefficients(
            self.fovDegrees, self.fovRays)

        # Create player object
        startPos = self.level.get_start_block() * BLOCK_SIZE
        startPos[0] = startPos.x + (BLOCK_SIZE // 2)  # Center vertically
        startPos[1] = startPos.y + (BLOCK_SIZE // 2)  # Center horizontally
        self.player = Player(startPos, 0, self.raycasting, self.fovRays)

        # Create win screen
        self.winScreen = pygame.Surface(windowSize, flags=pygame.SRCALPHA)
        self.winScreen.fill(
            (CEIL_COLOR[0], CEIL_COLOR[1], CEIL_COLOR[2], WIN_SCREEN_OPACITY))
        youWon = self.font.render("You won!", False, TEXT_COLOR)
        pressQ = self.font.render("Press 'Q' to quit.", False, TEXT_COLOR)
        self.winScreen.blit(youWon, (8, 8))
        self.winScreen.blit(pressQ, (8, 40))
예제 #5
0
class Game:
    """
    Represents state of the game. Initializes pygame and all necessary variables and
    constants on object creation.
    """
    def __init__(self, level, windowSize, totalRays, fovDegrees, targetFps):
        self.level = level
        self.windowSize = windowSize
        self.fovDegrees = fovDegrees
        self.targetFps = targetFps

        self.moveSpeed = NORMALIZED_MOVE * (60 / targetFps)
        self.turnSpeed = NORMALIZED_TURN * (60 / targetFps) * (totalRays / 600)
        self.cataclysmSpeed = NORMALIZED_CATACLYSM * 0.00001 * (60 / targetFps)

        self.raycasting = None
        self.screen = None
        self.font = None
        self.minimap = None
        self.fovRays = None
        self.pixelsPerRay = None
        self.distanceToProjection = None
        self.player = None
        self.winScreen = None

        # Initialize raycasting logic
        self.raycasting = Raycasting(totalRays, BLOCK_SIZE, self.level)

        # Initialize pygame
        pygame.init()
        pygame.display.set_caption("Raycasting labyrint")
        self.screen = pygame.display.set_mode(self.windowSize)

        # Prepare font rendering
        pygame.font.init()
        self.font = pygame.font.SysFont("Sans Serif", 30)

        # Prepare minimap
        minimapSize = self.level.get_size() * BLOCK_SIZE // MINIMAP_SIZE_DIV
        self.minimap = pygame.Surface((minimapSize.x, minimapSize.y))

        # Compute fov related stuff
        self.fovRays = self.raycasting.degrees_to_ray_number(self.fovDegrees)
        self.pixelsPerRay = windowSize[0] // (totalRays //
                                              (360 // self.fovDegrees))

        # Compute distance between player and the projection plane (also fov stuff)
        self.distanceToProjection = int(
            (PROJECTION_WIDTH) / (tan(radians(self.fovDegrees / 2))))

        # Prepare fisheye correction
        self.fisheyeCoefficients = self.raycasting.fisheye_coefficients(
            self.fovDegrees, self.fovRays)

        # Create player object
        startPos = self.level.get_start_block() * BLOCK_SIZE
        startPos[0] = startPos.x + (BLOCK_SIZE // 2)  # Center vertically
        startPos[1] = startPos.y + (BLOCK_SIZE // 2)  # Center horizontally
        self.player = Player(startPos, 0, self.raycasting, self.fovRays)

        # Create win screen
        self.winScreen = pygame.Surface(windowSize, flags=pygame.SRCALPHA)
        self.winScreen.fill(
            (CEIL_COLOR[0], CEIL_COLOR[1], CEIL_COLOR[2], WIN_SCREEN_OPACITY))
        youWon = self.font.render("You won!", False, TEXT_COLOR)
        pressQ = self.font.render("Press 'Q' to quit.", False, TEXT_COLOR)
        self.winScreen.blit(youWon, (8, 8))
        self.winScreen.blit(pressQ, (8, 40))

    def run(self):
        """
        Main game loop.
        """

        clock = pygame.time.Clock()
        keepGoing = True

        playerHasMoved = False
        timerOn = False
        timer = 0.0

        win = False  # Set to True when player reaches the flag
        drawMinimap = False

        cataclysm = 0.0  # Win screen animation time
        cataclysmedRays = [0] * self.raycasting.get_total_rays()

        while keepGoing:
            #
            # Events and user input
            #

            # Handle events
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    keepGoing = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:  # If 'q' was pressed down
                        # Quit game
                        keepGoing = False
                    if event.key == pygame.K_m:  # If 'm' was pressed down
                        # Toggle minimap
                        drawMinimap = not drawMinimap

            # Player and camera movement
            pressedKeys = pygame.key.get_pressed()

            self.moveSpeed *= 1.0 - cataclysm

            if pressedKeys[pygame.K_w]:
                self.player.move_forward(self.moveSpeed)

                if not playerHasMoved:
                    playerHasMoved = True
                    timerOn = True
            if pressedKeys[pygame.K_s]:
                self.player.move_backward(self.moveSpeed)

                if not playerHasMoved:
                    playerHasMoved = True
                    timerOn = True
            if pressedKeys[pygame.K_a]:
                self.player.move_left(self.moveSpeed)

                if not playerHasMoved:
                    playerHasMoved = True
                    timerOn = True
            if pressedKeys[pygame.K_d]:
                self.player.move_right(self.moveSpeed)

                if not playerHasMoved:
                    playerHasMoved = True
                    timerOn = True

            if pressedKeys[pygame.K_j]:
                self.player.turn(-self.turnSpeed)
            if pressedKeys[pygame.K_l]:
                self.player.turn(self.turnSpeed)

            #
            # Win stuff
            #

            # Check if flag was reached
            if (not win) and self.player.get_pos(
            ) // BLOCK_SIZE == self.level.get_flag_block():
                win = True
                timerOn = False

                self.moveSpeed /= 2.0
                self.turnSpeed //= 2

            # Animate cataclysm
            i = 0
            while i < len(cataclysmedRays):
                if cataclysmedRays[i] < 3:
                    if random() < cataclysm:
                        cataclysmedRays[i] = 1
                    if random() < cataclysm:
                        cataclysmedRays[i] = 2
                    if random() < cataclysm:
                        cataclysmedRays[i] = 3
                i += 1

            if win:
                if cataclysm < 1.0:
                    cataclysm += self.cataclysmSpeed
                else:
                    cataclysm = 1.0

            #
            # Rendering
            #

            # Draw floor and ceiling
            self.screen.fill(FLOOR_COLOR)
            ceilRect = pygame.Rect(0, 0, self.windowSize[0],
                                   self.windowSize[1] // 2)
            pygame.draw.rect(self.screen, CEIL_COLOR, ceilRect)

            # Render walls
            distances, intersections, flagDistances = self.raycasting.cast_rays(  # Cast rays
                self.player.get_left_ray(),
                self.player.get_right_ray(),
                self.player.get_pos(),
                messUpRays=cataclysmedRays)
            for i, distance in enumerate(distances):
                if not distance is None:
                    #
                    # Draw a column coresponding to each cast ray
                    #

                    currPixel = i * self.pixelsPerRay

                    # Compute height of the column
                    if -1.0 < distance < 1.0:
                        height = self.windowSize[1]
                    else:
                        height = self.windowSize[
                            1] / distance * self.distanceToProjection

                    # Apply fisheye correction
                    height *= self.fisheyeCoefficients[i]

                    # Compute color of the column
                    colorCoeficient = distance / RENDER_DISTANCE
                    if colorCoeficient > 1.0:
                        colorCoeficient = 1.0
                    red = WALL_COLOR[0] * (1.0 - colorCoeficient) + \
                          CEIL_COLOR[0] * colorCoeficient
                    green = WALL_COLOR[1] * (1.0 - colorCoeficient) + \
                            CEIL_COLOR[1] * colorCoeficient
                    blue = WALL_COLOR[2] * (1.0 - colorCoeficient) + \
                           CEIL_COLOR[2] * colorCoeficient
                    color = (red, green, blue)

                    # Draw the column
                    column = pygame.Rect(
                        currPixel, self.windowSize[1] // 2 - (height // 2),
                        self.pixelsPerRay, height)
                    pygame.draw.rect(self.screen, color, column)

            # Render flag
            for i, distance in enumerate(flagDistances):
                if not distance is None:
                    currPixel = i * self.pixelsPerRay

                    # Compute height of the column
                    if -0.1 < distance < 0.1:
                        height = self.windowSize[1]
                    else:
                        height = self.windowSize[
                            1] / distance * self.distanceToProjection / FLAG_HEIGHT_DIV

                    # Apply fisheye correction
                    height *= self.fisheyeCoefficients[i]

                    # Compute color of the column
                    colorCoeficient = distance / RENDER_DISTANCE
                    if colorCoeficient > 1.0:
                        colorCoeficient = 1.0
                    red = FLAG_COLOR[0] * (1.0 - colorCoeficient) + \
                          CEIL_COLOR[0] * colorCoeficient
                    green = FLAG_COLOR[1] * (1.0 - colorCoeficient) + \
                            CEIL_COLOR[1] * colorCoeficient
                    blue = FLAG_COLOR[2] * (1.0 - colorCoeficient) + \
                           CEIL_COLOR[2] * colorCoeficient
                    color = (red, green, blue)

                    # Draw the column
                    column = pygame.Rect(
                        currPixel, self.windowSize[1] // 2 - (height // 2),
                        self.pixelsPerRay, height)
                    pygame.draw.rect(self.screen, color, column)

            #
            # Draw UI
            #

            # Minimap
            if drawMinimap:
                # Draw walls on minimap
                self.minimap.fill(FLOOR_COLOR)
                for x, wall_column in enumerate(self.level.get_walls()):
                    for y, wall in enumerate(wall_column):
                        if wall:
                            rectSize = BLOCK_SIZE // MINIMAP_SIZE_DIV
                            rectX = x * rectSize
                            rectY = y * rectSize
                            rect = pygame.Rect(rectX, rectY, rectSize,
                                               rectSize)
                            pygame.draw.rect(self.minimap, WALL_COLOR, rect)

                # Draw flag on minimap
                x, y = self.level.get_flag_block()
                rectSize = BLOCK_SIZE // MINIMAP_SIZE_DIV
                rectX = x * rectSize
                rectY = y * rectSize
                rect = pygame.Rect(rectX, rectY, rectSize, rectSize)
                pygame.draw.rect(self.minimap, FLAG_COLOR, rect)

                # Draw player on minimap
                rectX = self.player.get_pos().x // MINIMAP_SIZE_DIV
                rectY = self.player.get_pos().y // MINIMAP_SIZE_DIV
                rectX -= MINIMAP_PLAYER_SIZE // 2
                rectY -= MINIMAP_PLAYER_SIZE // 2
                rect = pygame.Rect(rectX, rectY, MINIMAP_PLAYER_SIZE,
                                   MINIMAP_PLAYER_SIZE)
                pygame.draw.rect(self.minimap, MINIMAP_COLOR, rect)

                # Draw intersections (of rays that have been cast) on minimap
                for intersection in intersections:
                    if not intersection is None:
                        rectX = intersection.x // MINIMAP_SIZE_DIV
                        rectY = intersection.y // MINIMAP_SIZE_DIV
                        rect = pygame.Rect(rectX, rectY, 1, 1)
                        pygame.draw.rect(self.minimap, MINIMAP_COLOR, rect)

                # Blit minimap onto window
                self.screen.blit(self.minimap, (0, 0))

            # Fps
            fpsCount = ceil(clock.get_fps())
            fpsText = "fps: %d" % (fpsCount)
            color = TEXT_COLOR if fpsCount > (self.targetFps -
                                              10) else MINIMAP_COLOR
            fpsSurface = self.font.render(fpsText, False, color)
            self.screen.blit(fpsSurface,
                             (self.windowSize[0] - (7 * 10) - 8, 8))

            # Win screen
            if win:
                self.screen.blit(self.winScreen, (0, 0))

            # Timer
            timeText = "time: %.2f s" % (timer / 1000)
            timeSurface = self.font.render(timeText, False, TEXT_COLOR)
            self.screen.blit(timeSurface,
                             (self.windowSize[0] -
                              (12 * 10) - 8, self.windowSize[1] - 16 - 8))

            #
            # Finish drawing
            #

            pygame.display.flip()

            #
            # Time
            #

            if timerOn:
                timer += clock.get_time()

            clock.tick(self.targetFps)
예제 #6
0
class Main(object):
    def __init__(self, size):
        os.environ["SDL_VIDEO_CENTERED"] = "1"
        pygame.init()
        self.size = size
        self.screen = pygame.display.set_mode(self.size)
        self.surf = pygame.Surface(self.size)
        self.clock = pygame.time.Clock()
        self.running = True
        self.stage = 1
        self.ray1 = Raycasting((200, 320), (500, 50))
        self.ray2 = Raycasting((200, 320), (200, 50))
        self.ray3 = Raycasting((200, 320), (300, 50))
        self.make_wall(10)

        


    def main_loop(self, fps=0):
        while self.running:
            pygame.display.set_caption("Raytest. FPS: %i" % self.clock.get_fps())
            self.events()
            self.update()
            self.draw()
            pygame.display.flip()
            self.clock.tick(fps)

    def events(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                self.running = False
            elif event.type == KEYDOWN:
                self.key_down(event.key)
            elif event.type == MOUSEBUTTONDOWN:
                self.mouse_down(event.button, event.pos)

    def key_down(self, key):
        if key == K_1:
            self.stage = 1
        elif key == K_2:
            self.stage = 2
        elif key == K_3:
            self.stage = 3

    def mouse_down(self, button, pos):
        if self.stage == 1:
            if button == 1:
                self.ray2.pos = vec2d(pos)
            elif button == 3:
                self.ray2.target = vec2d(pos)
        elif self.stage == 2:
            if button == 1:
                self.ray3.pos = vec2d(pos)
            elif button == 3:
                self.ray3.target = vec2d(pos)
        elif self.stage == 3:
            if button == 1:
                self.ray1.pos = vec2d(pos)
            elif button == 3:
                self.ray1.target = vec2d(pos)

    def update(self):
        self.points = self.ray1.cast(self.wallgroup, 5, True)
        self.points2 = self.ray3.cast(self.wallgroup)
        self.collide = self.ray2.collisionany(self.wallgroup)
        print self.collide
        


        self.rectangles = []
        if self.points != []:
            for point in self.points:
                rectangle = pygame.Rect(5, 5, 5, 5)
                rectangle.center = point
                self.rectangles.append(rectangle)

        self.rectangles2 = []
        if self.points2 != []:
            for point in self.points2:
                rectangle = pygame.Rect(5, 5, 5, 5)
                rectangle.center = point
                self.rectangles2.append(rectangle)

        
        self.myLine = self.ray1.draw_ray()
        self.myLine2 = self.ray2.draw_ray()
        self.myLine3 = self.ray3.draw_ray()

        

    def draw(self):
        self.wallgroup.draw(self.surf)
        pygame.draw.line(self.surf, (255, 0, 255), self.myLine[0], self.myLine[1])
        pygame.draw.line(self.surf, (255, 0, 255), self.myLine2[0], self.myLine2[1])
        pygame.draw.line(self.surf, (255, 0, 255), self.myLine3[0], self.myLine3[1])

        if self.rectangles != []:
            for recta in self.rectangles:
                pygame.draw.rect(self.surf, (255, 255, 0), recta)

        if self.rectangles2 != []:
            for recta in self.rectangles2:
                pygame.draw.rect(self.surf, (255, 255, 0), recta)

        self.screen.blit(self.surf, (0,0))
        self.surf.fill((255, 255, 255))

    def make_wall(self, size):
        self.wallgroup = pygame.sprite.LayeredDirty()
        x = y = 200
        num = 1
        for wall in xrange(size):
            wall = Tile((x,y), num)
            self.wallgroup.add(wall)
            x += 32
            num += 1
예제 #7
0
 def _raycast(self, pos, tar):
     ray = Ray(pos, tar)
     return ray.cast(self.mob.collision.current_floor.walls, 5)
예제 #8
0
clock = pygame.time.Clock()
player = Player()
font = pygame.font.SysFont("Arial", 18)

def update_fps():
    fps = str(int(clock.get_fps()))
    fps_text = font.render(fps, 1, pygame.Color("coral"))
    return fps_text


# game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()

    player.move()
    screen.fill(BLACK)
 
    
    pygame.draw.rect(screen,SKY,(0,0,WIDTH,HEIGHT//2))
    pygame.draw.rect(screen, GROUND, (0, HEIGHT//2, WIDTH, HEIGHT // 2))

    
    Raycasting(screen,player)
    drawMinimap(screen, player, world_map,3)
    
    screen.blit(update_fps(), (10, 0))

    pygame.display.flip()
    clock.tick(FPS)