魂斗罗程序(学习 Python 之 Pygame 开发魂斗罗(十三))
继续编写魂斗罗
在上次的博客学习 Python 之 Pygame 开发魂斗罗(十二)中 ,我们解决了一些问题 ,这次我们新加入一个敌人 ,那我们就开始吧
下面是图片的素材
链接:https://pan.baidu.com/s/1X7tESkes_O6nbPxfpHD6hQ?pwd=hdly
提取码:hdly1. 创建敌人2类
这次新加入一个敌人 ,首先创建敌人2的类
class Enemy2(pygame.sprite.Sprite): def __init__(self, x, y, direction, currentTime): pygame.sprite.Sprite.__init__(self) self.r = 0.0 self.bulletPosition = 0 self.rightImage = loadImage(../Image/Enemy/Enemy2/right.png) self.rightUpImage = loadImage(../Image/Enemy/Enemy2/rightUp.png) self.rightDownImage = loadImage(../Image/Enemy/Enemy2/rightDown.png) self.leftImage = loadImage(../Image/Enemy/Enemy2/right.png, True) self.leftUpImage = loadImage(../Image/Enemy/Enemy2/rightUp.png, True) self.leftDownImage = loadImage(../Image/Enemy/Enemy2/rightDown.png, True) self.type = 2 if direction == Direction.RIGHT: self.image = self.rightImage else: self.image = self.leftImage self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.center = self.rect.x + self.rect.width / 2, self.rect.y + self.rect.height / 2 self.isDestroy = False self.isFiring = False self.life = 1 self.lastTime = currentTime self.n = 0 # 计算时间 self.t = 0这里设置了一下加载的图片 ,还有一些必要的属性
下面是这个敌人的图片
这个敌人发射子弹的放心是玩家的中心 ,所以我们要计算出玩家的中心 ,也要计算出敌人的中心 ,这样可以计算出玩家与敌人相距的x方向的距离和y方向的距离
所以我们要有一个计算敌人中心的函数
def getCenter(self): return self.rect.x + self.rect.width / 2, self.rect.y + self.rect.height / 2有了计算中心的函数 ,现在就可以写draw()函数了
2. 编写敌人2类的draw()函数
这个敌人一共有6种状态 ,下面是示意图
这六个姿势就是6个图片
敌人的枪口始终对着我们的中心位置 ,因为在魂斗罗游戏中 ,这个敌人发射的子弹是一直跟着玩家的,玩家移动 ,它就移动枪口的位置 ,因此就有这6中姿势
下面我们首先计算出敌人和玩家的距离
我们通过图,可以看出x和y分别都是用人物的中心进行计算而得来的
∠1是玩家与敌人中心连线与水平方向的夹角 ,这个交的大小决定着敌人的姿势
这张图片中的蓝色线 ,是45度的线 ,所以我们把姿势定下来
当玩家在敌人左边时 ,计算玩家与敌人的夹角 ,如果大于45度 ,敌人就是姿势6 ,如果小于-45度 ,敌人状态就是姿势5 ,其他敌人的姿势就是通过这样的方法计算出来的
下面我们写代码
def draw(self, window: pygame.Surface, player: PlayerOne, currentTime): # 获取玩家中心 playerCenter = player.getCenter() # 获取敌人中心 center = self.getCenter() # 计算距离 y = playerCenter[1] - center[1] x = playerCenter[0] - center[0] # 设置存放夹角的变量 r = 0 # 当 x = 0时 ,此时玩家在敌人的正上方 ,我们不做任何操作 if x != 0: # 如果玩家在敌人的正上方 ,计算角度 r = math.atan(y / x) * 180 / math.pi # 设置变量,用来记录敌人的姿势 ,敌人的姿势就是发射子弹时的样子 self.bulletPosition = 1 # 根据距离的正负关系判断玩家在敌人的左边还是右边 if x >= 0: if -45 < r < 45: self.bulletPosition = 2 self.image = self.rightImage elif r >= 45: self.bulletPosition = 3 self.image = self.rightDownImage elif r <= -45: self.bulletPosition = 1 self.image = self.rightUpImage else: if -45 < r < 45: self.bulletPosition = 5 self.image = self.leftImage elif r <= -45: self.bulletPosition = 4 self.image = self.leftDownImage elif r >= 45: self.bulletPosition = 6 self.image = self.leftUpImage self.r = r window.blit(self.image, self.rect)代码中我写了注释 ,这段代码的意思上面也说明明白了,大概就是计算出玩家和敌人的x方向距离和y方向距离 ,然后计算夹角 ,根据夹角的度数设置敌人的姿势
现在关键的一步来了 ,发射子弹的位置有了 ,下面就是要思考:如何让敌人对着玩家中心发射?
我们来想一下 ,在高中我们学过 路程 = 时间×速度 ,现在我们知道了路程 ,就是敌人和玩家中心的距离差 ,要计算速度 ,那么需要知道时间 ,那么如何计算时间呢?有了时间 ,我们通过公式 速度 = 路程 / 时间 计算出速度了
我们可以把调用draw()函数的时间间隔记录下来 ,把这个的平均值设置为时间
于是我们在构造函数中,就有了这两个变量
self.n = 0 # 时间 self.t = 0n记录总的间隔数 ,t记录当前间隔的平均值
下面是计算思路:把每次调用该函数的时间间隔记录下来 ,根据调用的次数,计算出平均调用该函数的时间间隔 ,这个时间间隔就作为子弹的发射速度
self.n += 1 # 计算速度 total = self.t * self.n total = total + abs(currentTime - self.lastTime) self.lastTime = currentTime self.t = total * 1.0 / (self.n + 1)首先我们把上次调用该函数的时间记录到lastTime中 ,这次调用函数时的时间记录在currentTime 中 ,通过函数参数把currentTime值传进来
total = self.t * self.n
这句代码来计算总的时间间隔 ,因为最后我们要求两次调用该函数间隔的平均值
其次 ,我们使用下面的代码 ,把总的时间间隔和求出来
total = total + abs(currentTime - self.lastTime)
之后 self.lastTime = currentTime 记录当前的时间 ,准备进行下一次计算
最后 ,计算间隔的平均值
self.t = total * 1.0 / (self.n + 1)
举一个例子:
第一次计算出调用该函数的时间间隔是7ms ,此时n = 1 ,t = 7 ,子弹的速度就设置为7
第二次计算出调用该函数的时间间隔是8ms ,此时我们要计算8和7的平均值,此时 n = 2, t = (1 * 7 + 8) / 2= 7.5 ,所以此时的子弹速度为7.5
第二次计算出调用该函数的时间间隔是8ms ,此时我们还是要计算平均值,于是有t = (7.5 * 2 + 8)/ 3 ,这个结果还是记录为子弹的速度
以此类推 ,每次都会更新这个间隔时间 ,这个间隔时间就是子弹的速度
所以 ,我们最后就计算出来了子弹的速度了
把代码写到draw()函数中 ,就完成了draw()函数
def draw(self, window: pygame.Surface, player: PlayerOne, currentTime): self.n += 1 # 计算时间 total = self.t * self.n total = total + abs(currentTime - self.lastTime) self.lastTime = currentTime self.t = total * 1.0 / (self.n + 1) # 获取玩家中心 playerCenter = player.getCenter() # 获取敌人中心 center = self.getCenter() # 计算距离 y = playerCenter[1] - center[1] x = playerCenter[0] - center[0] # 设置存放夹角的变量 r = 0 # 当 x = 0时 ,此时玩家在敌人的正上方 ,我们不做任何操作 if x != 0: # 如果玩家在敌人的正上方 ,计算角度 r = math.atan(y / x) * 180 / math.pi # 设置变量 ,用来记录敌人的姿势 ,敌人的姿势就是发射子弹时的样子 self.bulletPosition = 1 # 根据距离的正负关系判断玩家在敌人的左边还是右边 if x >= 0: if -45 < r < 45: self.bulletPosition = 2 self.image = self.rightImage elif r >= 45: self.bulletPosition = 3 self.image = self.rightDownImage elif r <= -45: self.bulletPosition = 1 self.image = self.rightUpImage else: if -45 < r < 45: self.bulletPosition = 5 self.image = self.leftImage elif r <= -45: self.bulletPosition = 4 self.image = self.leftDownImage elif r >= 45: self.bulletPosition = 6 self.image = self.leftUpImage self.r = r window.blit(self.image, self.rect)3. 编写敌人越界消失函数
当敌人创建出来后 ,我们没有消灭 ,他就会随着玩家向右移动消失在玩家的窗口中,为了方式程序中存在大量的无效的敌人数据 ,我们要检查程序 ,让那些离开窗口的敌人自动销毁
编写检查函数
def checkPosition(self, x, y): if abs(self.rect.x - x) > 2000: self.isDestroy = True elif abs(self.rect.y - y) > 600: self.isDestroy = True当然,敌人1类也有该函数
4. 编写敌人开火函数
由于敌人2发射的子弹要对着玩家的方向发射 ,这里我们要修改子弹类
把子弹的初始速度变为0
修改构造函数参数
enemyType 是敌人的类型 ,类型不一样 ,发射位置不一样
parameter是一些额外的参数 ,敌人2发射子弹时 ,这里面就是传入一些必要的信息 ,用来计算
接下来将原来的逻辑进行修改
大部分代码没有改变 ,加了一个if-else语句
下面我们来写敌人2的子弹逻辑代码
elif enemyType == 2: self.index = 0 bulletPosition = parameter[0] player = parameter[1] playerCenter = player.getCenter() if player.isDown or player.isSquating: # 下蹲 、蹲下 、在水中时 ,让人物中心下移动 ,下移动代表y坐标的值相加 playerCenter = (playerCenter[0], playerCenter[1] + 8) elif player.isInWater: playerCenter = (playerCenter[0], playerCenter[1] + 15) t = parameter[2] # t *= 15 r = parameter[3] if bulletPosition == 1: self.rect.x += 19 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 2: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE s = -1 if r > 0: s = 1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 3: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 4: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 5: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE s = 1 if r > 0: s = -1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 6: self.rect.x += -1 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t self.xSpeed /= 5 self.ySpeed /= 5 self.image = self.images[self.index]完整的子弹类构造函数
def __init__(self, person, enemyType = 0, parameter = None): pygame.sprite.Sprite.__init__(self) self.images = [ loadImage(../Image/Bullet/bullet1.png) ] self.index = 0 # 速度 self.xSpeed = 1 self.ySpeed = 1 self.rect = pygame.Rect(person.rect) # 类型0表示不是敌人 if enemyType == 0: if person.isInWater: self.waterPosition(person) else: self.landPosition(person) # 敌人1 elif enemyType == 1: self.index = 0 if person.direction == Direction.RIGHT: self.rect.x += 27 * PLAYER_SCALE self.rect.y += 7 * PLAYER_SCALE self.ySpeed = 0 self.xSpeed = 7 else: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 7 * PLAYER_SCALE self.ySpeed = 0 self.xSpeed = -7 # 敌人2 elif enemyType == 2: self.index = 0 # 从额外参数中获取敌人的姿势 ,即子弹的发射位置 bulletPosition = parameter[0] # 获取玩家对象 player = parameter[1] # 获取玩家中心 playerCenter = player.getCenter() # 让人物中心下移 if player.isDown or player.isSquating: # 下蹲 、蹲下 、在水中时 ,让人物中心下移动 ,下移动代表y坐标的值相加 playerCenter = (playerCenter[0], playerCenter[1] + 8) elif player.isInWater: playerCenter = (playerCenter[0], playerCenter[1] + 15) # 获取子弹移动的时间 t = parameter[2] # t *= 15 # 获取敌人与玩家连线与水平方向的夹角 r = parameter[3] # 根据子弹的发射位置(敌人的姿势)计算敌人的发射子弹的位置和子弹的速度 if bulletPosition == 1: self.rect.x += 19 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE # 计算公式,|x0 - x1| / t = v self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 2: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE # s 表示方向这里可以直接根据r的大小 ,计算出子弹的速度是减少还是增加 # 减少表示向负方向移动 s = -1 if r > 0: s = 1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 3: self.rect.x += 25 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 4: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 25 * PLAYER_SCALE self.ySpeed = abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 5: self.rect.x += -1 * PLAYER_SCALE self.rect.y += 10 * PLAYER_SCALE s = 1 if r > 0: s = -1 self.ySpeed = s * abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t elif bulletPosition == 6: self.rect.x += -1 * PLAYER_SCALE self.rect.y += -1 * PLAYER_SCALE self.ySpeed = - abs(self.rect.y - playerCenter[1]) * 1.0 / t self.xSpeed = - abs(self.rect.x - playerCenter[0]) * 1.0 / t self.xSpeed /= 5 self.ySpeed /= 5 self.image = self.images[self.index] # 销毁开关 self.isDestroy = False之后我们来写玩家2类的开火函数了
def fire(self, enemyBulletList, player): i = random.randint(0, 30) if i == 5: self.isFiring = True enemyBulletList.append(Bullet(self, 2, (self.bulletPosition, player, self.t, self.r)))设置开火的频率 ,开火就创建一个子弹对象,把相应的额外参数传入
好 ,至此就完成了敌人2类
5. 把敌人2加入地图进行测试
来到主类 ,编写全局函数 ,用来创建敌人2
def generateEnemy2(x, y): enemy = Enemy2(x, y, MainGame.player1, pygame.time.get_ticks()) MainGame.enemyList.append(enemy) MainGame.allSprites.add(enemy) MainGame.enemyGroup.add(enemy)之后在generateEnemy()函数中调用
这个代码就是在指定的位置上创建一个敌人2
if -2005 < self.backRect.x < -2000: if self.enemyBoolList[2]: self.enemyBoolList[2] = False generateEnemy2(MainGame.player1.rect.x + 540, 465)接下来运行一下游戏 ,看看效果
出现了报错信息 ,应该是子弹类的构造函数进行了修改 ,所有创建子弹的函数都要修改 ,我们下面一一进行修改
首先进入enemyUpdate()函数 ,由于我们加入了敌人2 ,所以调用draw()函数的时候要进行判断了 ,因为敌人1和敌人2的draw()函数参数不一样
将代码进行修改
def enemyUpdate(enemyList, enemyBulletList): # 遍历整个敌人列表 for enemy in enemyList: if enemy.type == 1: if enemy.isDestroy: enemyList.remove(enemy) MainGame.allSprites.remove(enemy) MainGame.enemyGroup.remove(enemy) else: enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y) enemy.draw(pygame.time.get_ticks()) enemy.move(pygame.time.get_ticks()) enemy.fire(enemyBulletList) elif enemy.type == 2: if enemy.isDestroy: enemyList.remove(enemy) MainGame.allSprites.remove(enemy) MainGame.enemyGroup.remove(enemy) else: enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y) enemy.draw(MainGame.window, MainGame.player1, pygame.time.get_ticks()) enemy.fire(enemyBulletList, MainGame.player1)变化的地方就是敌人2的draw()函数和fire()函数多了一个参数
之后给敌人1类加入成员变量type
self.type = 1我们再运行游戏 ,看看问题
可以看到敌人发射子弹的方向一直向着玩家
但是还有个问题 ,就是玩家屏幕向右移动的时候,子弹会停下来
这应该是窗口移动时 ,没让子弹也一起移动
我们修改一下mapObjectMove()函数 ,加入下面的代码
理论上,爆炸也应该加入进去 ,我们没有加入 ,我们把爆炸也一同加入
def mapObjectMove(self): for sprite in MainGame.allSprites: sprite.rect.x -= self.cameraAdaption for collider in MainGame.playerColliderGroup: collider.rect.x -= self.cameraAdaption for collider in MainGame.colliderStack: collider.rect.x -= self.cameraAdaption for collider in MainGame.enemyColliderGroup: collider.rect.x -= self.cameraAdaption for bullet in MainGame.enemyBulletList: bullet.rect.x -= self.cameraAdaption for explode in MainGame.explodeList: explode.rect.x -= self.cameraAdaption好 ,接下来我们再运行一下游戏 ,看看效果
可以看到 ,子弹也会随着窗口移动而移动啦
我们现在就完了敌人2了 ,下面就是加入其他敌人和BOSS了
完整的主类代码
import copy import sys import pygame from Constants import * from PlayerOne import PlayerOne from Collider import Collider from Enemy1 import Enemy1 from Explode import Explode from Enemy2 import Enemy2 def drawPlayerOneBullet(player1BulletList): for bullet in player1BulletList: if bullet.isDestroy: player1BulletList.remove(bullet) else: bullet.draw(MainGame.window) bullet.move() bullet.collideEnemy(MainGame.enemyList, MainGame.explodeList) def enemyUpdate(enemyList, enemyBulletList): # 遍历整个敌人列表 for enemy in enemyList: if enemy.type == 1: if enemy.isDestroy: enemyList.remove(enemy) MainGame.allSprites.remove(enemy) MainGame.enemyGroup.remove(enemy) else: enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y) enemy.draw(pygame.time.get_ticks()) enemy.move(pygame.time.get_ticks()) enemy.fire(enemyBulletList) elif enemy.type == 2: if enemy.isDestroy: enemyList.remove(enemy) MainGame.allSprites.remove(enemy) MainGame.enemyGroup.remove(enemy) else: enemy.checkPosition(MainGame.player1.rect.x, MainGame.player1.rect.y) enemy.draw(MainGame.window, MainGame.player1, pygame.time.get_ticks()) enemy.fire(enemyBulletList, MainGame.player1) def updateEnemyPosition(): # 遍历全部敌人列表 for enemy in MainGame.enemyList: # 创建一个复制 t = copy.copy(enemy) t.rect.y += 1 # 让复制的y加1 ,看看有没有发生碰撞 ,这里看的碰撞是enemyColliderGroup中的碰撞 collide = pygame.sprite.spritecollideany(t, MainGame.enemyColliderGroup) # 没有发生碰撞 ,让敌人下落 if not collide: enemy.rect.y += 4 enemy.isFalling = True # 改变下落时的图片 enemy.image = enemy.rightFallImage if enemy.direction == Direction.RIGHT else enemy.leftFallImage else: enemy.isFalling = False # 如果与河发生碰撞 ,表示敌人落到了水中 ,那么敌人直接死亡 if collide in MainGame.enemyRiverGroup: enemy.isDestroy = True MainGame.explodeList.append(Explode(enemy)) t.rect.y -= 1 def drawEnemyBullet(enemyBulletList): for bullet in enemyBulletList: if bullet.isDestroy: enemyBulletList.remove(bullet) else: bullet.draw(MainGame.window) bullet.move() if bullet.collidePlayer(MainGame.player1, MainGame.explodeList): initPlayer1(MainGame.player1.life) def initLand(): land1 = Collider(81, 119 * MAP_SCALE, 737 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) # land1 = Collider(81, 119 * MAP_SCALE, 8000 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land2 = Collider(400, 151 * MAP_SCALE, 96 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land3 = Collider(640, 183 * MAP_SCALE, 33 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land4 = Collider(880, 183 * MAP_SCALE, 33 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land5 = Collider(720, 215 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land6 = Collider(1040, 154 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land7 = Collider(1600, 166 * MAP_SCALE, 3 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land8 = Collider(1120 * RATIO, 215 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land9 = Collider(1650 * RATIO, 119 * MAP_SCALE, 5 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land10 = Collider(2185 * RATIO, 119 * MAP_SCALE, 8 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land11 = Collider(2595 * RATIO, 215 * MAP_SCALE, 3 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land12 = Collider(2770 * RATIO, 167 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land13 = Collider(2535 * RATIO, 87 * MAP_SCALE, 16 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land14 = Collider(2950 * RATIO, 151 * MAP_SCALE, 7 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land15 = Collider(3185 * RATIO, 215 * MAP_SCALE, 6 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land16 = Collider(3420 * RATIO, 119 * MAP_SCALE, 7 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land17 = Collider(3537 * RATIO, 183 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land18 = Collider(3715 * RATIO, 183 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land19 = Collider(3890 * RATIO, 167 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land20 = Collider(3775 * RATIO, 87 * MAP_SCALE, 5 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land21 = Collider(4010 * RATIO, 151 * MAP_SCALE, 3 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land22 = Collider(4125 * RATIO, 119 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land23 = Collider(4304 * RATIO, 151 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land24 = Collider(4304 * RATIO, 216 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land25 = Collider(4361 * RATIO, 183 * MAP_SCALE, 3 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land26 = Collider(4537 * RATIO, 119 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land27 = Collider(4598 * RATIO, 87 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land28 = Collider(4657 * RATIO, 167 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land29 = Collider(4598 * RATIO, 216 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land30 = Collider(4776 * RATIO, 119 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land31 = Collider(4835 * RATIO, 151 * MAP_SCALE, 5 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land32 = Collider(5010 * RATIO, 216 * MAP_SCALE, 3 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land33 = Collider(5250 * RATIO, 183 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land34 = Collider(5423 * RATIO, 151 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land35 = Collider(5543 * RATIO, 119 * MAP_SCALE, 4 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land36 = Collider(5601 * RATIO, 167 * MAP_SCALE, 3 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land37 = Collider(5541 * RATIO, 216 * MAP_SCALE, 8 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land38 = Collider(5776 * RATIO, 151 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) land39 = Collider(5836 * RATIO, 183 * MAP_SCALE, 1 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) MainGame.playerLandGroup = pygame.sprite.Group( land1, land2, land3, land4, land5, land6, land7, land8, land9, land10, land11, land12, land13, land14, land15, land16, land17, land18, land19, land20, land21, land22, land23, land24, land25, land26, land27, land28, land29, land30, land31, land32, land33, land34, land35, land36, land37, land38, land39 ) eland1 = Collider(81, 119 * MAP_SCALE, 737 * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) eland8 = Collider(1120 * RATIO, 215 * MAP_SCALE, 2 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) eland9 = Collider(1650 * RATIO, 119 * MAP_SCALE, 5 * LAND_LENGTH * MAP_SCALE, LAND_THICKNESS * MAP_SCALE) eland10 = Collider(2185 * RATIO,%创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!