【问题标题】:2d pygame scrolling with Sprites and tile based map使用 Sprites 和基于图块的地图进行 2d pygame 滚动
【发布时间】:2020-09-04 12:46:33
【问题描述】:

我目前正在尝试使用滚动相机在 python 中制作 2d 平台游戏。最初我只使用 rect 样式的对象制作这个游戏,但与仅使用 sprite 相比,这使得碰撞非常困难。

所以现在我正在为敌人和主要玩家使用精灵重写这个游戏,但我无法弄清楚为什么滚动功能将不再起作用。这似乎是一个扩展问题,但我不知道。

当我关闭滚动时,游戏运行正常。

谢谢你们,如果你看到任何跳出来的东西,请告诉我。 抱歉代码有点乱,我还在习惯整个 pygame 布局。

import pygame, sys

clock = pygame.time.Clock()

from pygame.locals import *
pygame.init() # initiates pygame

pygame.display.set_caption('Pygame Platformer')

WINDOW_SIZE = (1200,800)

screen = pygame.display.set_mode(WINDOW_SIZE,0,32) # initiate the window

display = pygame.Surface((150,100)) # used as the surface for rendering, which is scaled

moving_right = False
moving_left = False
vertical_momentum = 0
air_timer = 0
scroll = [0, 0]
class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((8, 8))
        self.image.fill((255, 0, 0))
        self.rect = self.image.get_rect()
        self.rect.centerx = 100
        self.rect.bottom = 50
        self.isJump = False
        self.jumpCount = 5
    def update(self):
        self.speedx = 0
        self.rect.x += self.speedx

class Mob(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((10, 10))
        self.image.fill((255, 255, 0))
        self.rect = self.image.get_rect()
        self.rect.centerx = y
        self.rect.bottom = x
        self.speedx = 0
        self.speedy = 0

    def update(self):
        self.speedx = 0
        self.speedy = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_LEFT]:
            self.speedx = -10
        if keystate[pygame.K_RIGHT]:
            self.speedx = 10
        if keystate[pygame.K_SPACE]:
            self.speedy = -30
        self.rect.x += 0
        self.rect.y += 0
#def load_map(path):
 #   f = open(path + '.txt', 'r')
  #  data = f.read()
   # f.close()
    #data = data.split('\n')
   # game_map = []
   # for row in data:
    #    game_map.append(list(row))
   # return game_map

#ame_map = load_map('data/pictures/map')
game_map = [['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','2','2','2','2','2','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['2','2','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','2'],
            ['1','1','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1']]

grass_img = pygame.image.load('data/pictures/Purple_grass.png')
dirt_img = pygame.image.load('data/pictures/purple_tile.png')

player = Player()

def collision_test(rect,tiles):
    hit_list = []
    for tile in tiles:
        if rect.colliderect(tile):
            hit_list.append(tile)
    return hit_list

def move(rect,movement,tiles):
    collision_types = {'top':False,'bottom':False,'right':False,'left':False}
    rect.x += movement[0]
    hit_list = collision_test(rect,tiles)
    for tile in hit_list:
        if movement[0] > 0:
            rect.right = tile.left
            collision_types['right'] = True
        elif movement[0] < 0:
            rect.left = tile.right
            collision_types['left'] = True
    rect.y += movement[1]
    hit_list = collision_test(rect,tiles)
    for tile in hit_list:
        if movement[1] > 0:
            rect.bottom = tile.top
            collision_types['bottom'] = True
        elif movement[1] < 0:
            rect.top = tile.bottom
            collision_types['top'] = True
    return rect, collision_types




all_sprites = pygame.sprite.Group()
mobs = []
mob1 = Mob(10,10)
mobs.append(mob1)
all_sprites.add(player,mobs)
while True: # game loop
    display.fill((146,244,255)) # clear screen by filling it with blue
    #scroll
    scroll[0] += (player.rect.x - scroll[0] -100 ) / 10
    scroll[1] += (player.rect.y - scroll[1] -52) / 10
    all_sprites.update()

    tile_rects = []
    y = 0
    for layer in game_map:
        x = 0
        for tile in layer:
            if tile == '1':
                display.blit(dirt_img, (x * 8 - int(scroll[0]), y * 8 - int(scroll[1])))
            if tile == '2':
                display.blit(grass_img, (x * 8 - int(scroll[0]), y * 8 - int(scroll[1])))
            if tile != '0':
                tile_rects.append(pygame.Rect(x * 8, y * 8, 8, 8))
            x += 1
        y += 1

    player_movement = [0,0]
    if moving_right == True:
        player_movement[0] += 1
    if moving_left == True:
        player_movement[0] -= 1
    player_movement[1] += vertical_momentum
    vertical_momentum += 0.3
    if vertical_momentum > 3:
        vertical_momentum = 3

    player.rect,collisions = move(player.rect,player_movement,tile_rects)

    if collisions['bottom'] == True:
        air_timer = 0
        player.jumpCount = 0
    else:
        air_timer += 1


    for mob in mobs:
        if pygame.sprite.collide_rect(player,mob):
            #mob.image.fill((255,0,255))
            mobs.pop(mobs.index(mob))
            print("collide")
            all_sprites.remove(mob)

        else:
            mob.image.fill((255,255,0))

    all_sprites.draw(display)


    for event in pygame.event.get(): # event loop
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_RIGHT:
                moving_right = True
            if event.key == K_LEFT:
                moving_left = True
            if event.key == K_SPACE:
                if air_timer < 6:
                    vertical_momentum = -5
        if event.type == KEYUP:
            if event.key == K_RIGHT:
                moving_right = False
            if event.key == K_LEFT:
                moving_left = False
        
    screen.blit(pygame.transform.scale(display,WINDOW_SIZE),(0,0))
    pygame.display.update()
    clock.tick(60)

【问题讨论】:

  • 我需要map.txt文件来运行游戏。
  • 对不起,我编辑了一个帖子,所以有一个基本的集成地图
  • if tile != '0': - 当你附加瓷砖时,你应该调整瓷砖的矩形滚动:tile_rects.append(pygame.Rect(x * 8 - int(scroll[0]), y * 8 - int(scroll[1]), 8, 8))
  • 我刚刚尝试过,我遇到了一些疯狂的碰撞错误,它把我扔到屏幕周围并穿过墙壁。我不确定滚动会如何影响我的碰撞,但我猜它是可能的。
  • 如果出现问题,请使用print() 查看不同位置的变量值 - 然后您可以检查它们是否正确。它被称为print debuging

标签: python scroll pygame


【解决方案1】:

首先:你应该在所有移动和碰撞之后计算scroll

第二:你必须从所有对象中减去scroll——甚至是玩家和生物

for item in all_sprites:
    display.blit(item.image, (item.rect.x - scroll[0], item.rect.y - scroll[1]))

最少的工作代码。

scroll 可以,但不流畅,所以我更喜欢更简单的版本

scroll[0] = int(player.rect.centerx - 75) # surface_width//2
scroll[1] = int(player.rect.centery - 50) # surface_height//2

两者都在代码中,但在 cmets 中

import pygame, sys
from pygame.locals import *

# --- constants ---

WINDOW_SIZE = (1200, 800)

# --- classes ---

class Player(pygame.sprite.Sprite):
    
    def __init__(self):
        #pygame.sprite.Sprite.__init__(self)
        super().__init__()
        
        self.image = pygame.Surface((8, 8))
        self.image.fill((255, 0, 0))
        
        self.rect = self.image.get_rect()
        self.rect.centerx = 100
        self.rect.bottom = 50
        
        self.isJump = False
        self.jumpCount = 5
        
    def update(self):
        self.speedx = 0
        self.rect.x += self.speedx

class Mob(pygame.sprite.Sprite):
    
    def __init__(self,x,y):
        #pygame.sprite.Sprite.__init__(self)
        super().__init__()
        
        self.image = pygame.Surface((10, 10))
        self.image.fill((255, 255, 0))
        
        self.rect = self.image.get_rect()
        self.rect.centerx = y
        self.rect.bottom = x
        
        self.speedx = 0
        self.speedy = 0

    def update(self):
        self.speedx = 0
        self.speedy = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_LEFT]:
            self.speedx = -10
        if keystate[pygame.K_RIGHT]:
            self.speedx = 10
        if keystate[pygame.K_SPACE]:
            self.speedy = -30
        self.rect.x += 0
        self.rect.y += 0

# --- functions ---

#def load_map(path):
 #   f = open(path + '.txt', 'r')
  #  data = f.read()
   # f.close()
    #data = data.split('\n')
   # game_map = []
   # for row in data:
    #    game_map.append(list(row))
   # return game_map

def collision_test(rect,tiles):
    hit_list = []

    for tile in tiles:
        if rect.colliderect(tile):
            hit_list.append(tile)
            
    return hit_list

def move(rect,movement,tiles):
    collision_types = {'top':False,'bottom':False,'right':False,'left':False}
    
    rect.x += movement[0]
    hit_list = collision_test(rect,tiles)
    
    for tile in hit_list:
        if movement[0] > 0:
            rect.right = tile.left
            collision_types['right'] = True
        elif movement[0] < 0:
            rect.left = tile.right
            collision_types['left'] = True
            
    rect.y += movement[1]
    hit_list = collision_test(rect,tiles)
    
    for tile in hit_list:
        if movement[1] > 0:
            rect.bottom = tile.top
            collision_types['bottom'] = True
        elif movement[1] < 0:
            rect.top = tile.bottom
            collision_types['top'] = True
            
    return rect, collision_types

# --- main ---

# you could put in class Map
#ame_map = load_map('data/pictures/map')
game_map = [['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','2','2','2','2','2','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['2','2','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','2'],
            ['1','1','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1']]


# - init -

pygame.init() 

pygame.display.set_caption('Pygame Platformer')

screen = pygame.display.set_mode(WINDOW_SIZE,0,32) # initiate the window

display = pygame.Surface((150,100)) # used as the surface for rendering, which is scaled

moving_right = False   # you could put in class Player
moving_left = False    # you could put in class Player
vertical_momentum = 0  # you could put in class Player
air_timer = 0          # you could put in class Player
scroll = [0, 0]        # you could put in class Player

#grass_img = pygame.image.load('data/pictures/Purple_grass.png')
#dirt_img = pygame.image.load('data/pictures/purple_tile.png')

grass_img = pygame.surface.Surface((8,8))  # you could put in class Map
grass_img.fill((0, 255, 0))                # you could put in class Map
                    
dirt_img = pygame.surface.Surface((8,8))  # you could put in class Map
dirt_img.fill((255, 64, 64))              # you could put in class Map

player = Player()
mobs = [Mob(10, 10)]

all_sprites = pygame.sprite.Group()
all_sprites.add(player,mobs)

# - you can get it once - # you could put in class Map

tile_rects = []
for y, layer in enumerate(game_map):
    for x, tile in enumerate(layer):
        if tile != '0':
            tile_rects.append(pygame.Rect(x * 8, y * 8, 8, 8))

# - loop -

clock = pygame.time.Clock()

while True:

    # - all updates -
    
    all_sprites.update()

    player_movement = [0,0]
    if moving_right == True:
        player_movement[0] += 1
    if moving_left == True:
        player_movement[0] -= 1
    player_movement[1] += vertical_momentum
    vertical_momentum += 0.3
    if vertical_momentum > 3:
        vertical_momentum = 3

    player.rect,collisions = move(player.rect,player_movement,tile_rects)

    if collisions['bottom'] == True:
        air_timer = 0
        player.jumpCount = 0
    else:
        air_timer += 1

    for mob in mobs:
        if pygame.sprite.collide_rect(player,mob):
            #mob.image.fill((255,0,255))
            mobs.pop(mobs.index(mob))
            print("collide")
            all_sprites.remove(mob)

        else:
            mob.image.fill((255,255,0))

    # - all draws -
    
    # scroll calculate after all moves 
    scroll[0] = int(player.rect.centerx - 75) # surface_width//2
    scroll[1] = int(player.rect.centery - 50) # surface_height//2

    #scroll[0] += (player.rect.x - scroll[0] -100 ) / 10
    #scroll[1] += (player.rect.y - scroll[1] -52) / 10
    
    display.fill((146,244,255)) # clear screen by filling it with blue

    for y, layer in enumerate(game_map):
        for x, tile in enumerate(layer):
            if tile == '1':
                display.blit(dirt_img, (x * 8 - scroll[0], y * 8 - scroll[1]))
            if tile == '2':
                display.blit(grass_img, (x * 8 - scroll[0], y * 8 - scroll[1]))

    for item in all_sprites:
        display.blit(item.image, (item.rect.x - scroll[0], item.rect.y - scroll[1]))
    #all_sprites.draw(display)

    screen.blit(pygame.transform.scale(display, WINDOW_SIZE), (0, 0))
    pygame.display.update()
    clock.tick(60)

    # - all events -
    
    for event in pygame.event.get(): # event loop
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_RIGHT:
                moving_right = True
            if event.key == K_LEFT:
                moving_left = True
            if event.key == K_SPACE:
                if air_timer < 6:
                    vertical_momentum = -5
        if event.type == KEYUP:
            if event.key == K_RIGHT:
                moving_right = False
            if event.key == K_LEFT:
                moving_left = False
        

编辑:

具有更多类和其他更改的版本(即pygame.math.Vector2()

# PE8: all imports at the beginning
import pygame, sys
#from pygame.locals import * # PEP8: `import *` is not preferred

# --- constants ---

WINDOW_SIZE = (1200, 800)

# --- classes --- # PEP8: all classes before main part

class Player(pygame.sprite.Sprite):
                        # PEP8: empty line before method
    def __init__(self):
        #pygame.sprite.Sprite.__init__(self)  # Python 2 & 3
        super().__init__() # only Python 3
        
        self.image = pygame.Surface((8, 8))
        self.image.fill((255, 0, 255))

        self.rect = self.image.get_rect()
        self.rect.centerx = 100
        self.rect.bottom = 50
        
        self.is_jump = False   # PEP8: `lower_case_names` for variables
        self.jump_count = 5    # PEP8: `lower_case_names` for variables
        
        self.movement = pygame.math.Vector2(0, 0)
        self.speed = pygame.math.Vector2(0, 0)

        self.moving_right = False
        self.moving_left = False
        self.vertical_momentum = 0
        self.air_timer = 0

    def update(self):
        self.speed.x = 0
        #self.rect.x += self.speed.x

    def draw(self, screen, offset):
        screen.blit(self.image, self.rect.move(-offset))
        
class Mob(pygame.sprite.Sprite):
    
    def __init__(self,x,y):
        #pygame.sprite.Sprite.__init__(self)  # Python 2 & 3
        super().__init__() # only Python 3

        self.image = pygame.Surface((10, 10))
        self.image.fill((255, 255, 0))
        self.rect = self.image.get_rect()
        self.rect.centerx = y
        self.rect.bottom = x
        self.speedx = 0
        self.speedy = 0

    def update(self):
        self.speedx = 0
        self.speedy = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_LEFT]:
            self.speedx = -10
        if keystate[pygame.K_RIGHT]:
            self.speedx = 10
        if keystate[pygame.K_SPACE]:
            self.speedy = -30
        self.rect.x += 0
        self.rect.y += 0
        
    def draw(self, screen, offset):
        screen.blit(self.image, self.rect.move(-offset))
        
#def load_map(path):
 #   f = open(path + '.txt', 'r')
  #  data = f.read()
   # f.close()
    #data = data.split('\n')
   # game_map = []
   # for row in data:
    #    game_map.append(list(row))
   # return game_map

class Map():
    
    def __init__(self, game_map):
        self.game_map = game_map
        
        #self.grass_img = pygame.image.load('data/pictures/Purple_grass.png')
        #self.dirt_img = pygame.image.load('data/pictures/purple_tile.png')

        self.grass_img = pygame.surface.Surface((8,8))
        self.grass_img.fill((0, 255, 0))
                            
        self.dirt_img = pygame.surface.Surface((8,8))
        self.dirt_img.fill((255, 64, 64))

        # - you can calculate it only once -

        self.tile_rects = []

        for y, layer in enumerate(self.game_map):
            for x, tile in enumerate(layer):
                if tile != '0':
                    self.tile_rects.append(pygame.Rect(x*8, y*8, 8, 8))

    def draw(self, screen, offset):
        
        for y, layer in enumerate(self.game_map):
            for x, tile in enumerate(layer):
                if tile == '1':
                    display.blit(self.dirt_img, (x*8 - offset.x, y*8 - offset.y))
                elif tile == '2':
                    display.blit(self.grass_img, (x*8 - offset.x, y*8 - offset.y))
        
# --- functions --- # PEP8: all functions before main part

def collision_test(rect, tiles):
    hit_list = []
    
    for tile in tiles:
        if rect.colliderect(tile):
            hit_list.append(tile)
            
    return hit_list

def move(player, map_game):
    
    collision_types = {'top': False, 'bottom': False, 'right': False, 'left': False} # PEP8: spaces
    
    player.rect.x += player.movement.x
    
    hit_list = collision_test(player.rect, map_game.tile_rects)
    
    for tile in hit_list:
        if player.movement.x > 0:
            player.rect.right = tile.left
            collision_types['right'] = True
            break
        elif player.movement.x < 0:
            player.rect.left = tile.right
            collision_types['left'] = True
            break
            
    player.rect.y += player.movement.y
    
    hit_list = collision_test(player.rect, map_game.tile_rects)
    
    for tile in hit_list:
        if player.movement.y > 0:
            player.rect.bottom = tile.top
            collision_types['bottom'] = True
            break
        elif player.movement.y < 0:
            player.rect.top = tile.bottom
            collision_types['top'] = True
            break
            
    return collision_types

# --- main ---

#ame_map = load_map('data/pictures/map')
game_map = [['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','2','2','2','2','2','0','0','0','0','0','0','0'],
            ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
            ['2','2','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','2'],
            ['1','1','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
            ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1']]


# - init -

pygame.init()
pygame.display.set_caption('Pygame Platformer')

screen = pygame.display.set_mode(WINDOW_SIZE, 0, 32) # initiate the window

display = pygame.Surface((150, 100)) # used as the surface for rendering, which is scaled

scroll = pygame.math.Vector2(0, 0)

map_data = Map(game_map)
player = Player()
mobs = [Mob(10, 10), Mob(50, 50)]

all_sprites = pygame.sprite.Group()
all_sprites.add(player, mobs)

# - main loop -

clock = pygame.time.Clock()

while True:

    # - all updates -
    #all_sprites.update()

    player.movement.update(0, 0)
    
    if player.moving_right == True:
        player.movement.x += 1
            
    if player.moving_left == True:
        player.movement.x -= 1
        
    player.movement.y += player.vertical_momentum
    
    player.vertical_momentum += 0.3
    if player.vertical_momentum > 3:
        player.vertical_momentum = 3

    collisions = move(player, map_data)

    if collisions['bottom'] == True:
        player.air_timer = 0
        player.jump_count = 0
        player.vertical_momentum = 0
    else:
        player.air_timer += 1

        
    for mob in mobs:
        if pygame.sprite.collide_rect(player, mob):
            #mob.image.fill((255,0,255))
            mobs.pop(mobs.index(mob))
            print("collide")
            all_sprites.remove(mob)
        else:
            mob.image.fill((255,255,0))

    # - all draws -

    # scroll
    scroll.update(player.rect.centerx - 75, player.rect.centery - 50)

    offset = pygame.math.Vector2(int(scroll.x), int(scroll.y))

    display.fill((146, 244, 255))  # PEP8: spaces after `,`

    map_data.draw(display, offset)
    
    for item in all_sprites:
        item.draw(display, offset)

    screen.blit(pygame.transform.scale(display, WINDOW_SIZE), (0, 0))
    pygame.display.update()

    clock.tick(60)
    
    # - all events -

    for event in pygame.event.get(): # event loop
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
                
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                player.moving_right = True
            if event.key == pygame.K_LEFT:
                player.moving_left = True
            if event.key == pygame.K_SPACE:
                if player.air_timer < 6:
                    player.vertical_momentum = -5
                    
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                player.moving_right = False
            if event.key == pygame.K_LEFT:
                player.moving_left = False
                

【讨论】:

  • 非常感谢!这非常有帮助,我坚持了这么久。再次感谢!!!
猜你喜欢
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
相关资源
最近更新 更多