对于马里奥这个主角的制作相对会比较麻烦,因为马里奥多种形态,变大和变小,还有变成无敌那种状态,使用godot本身的动画效果比较不好处理,所以当时我就想了一些方法来处理。以下是马里奥的几种状态.
大致是这些变化,当然还有其它拉旗,进入到水管和变小之类的就不一一展示,大致的动画的制作基本一致。那么简单说下这些动画是怎么制作的,首先的话需要对马里奥的动画进行一个分类,应该每个动画会有不同的颜色和大小,当时基本是同一类型的。
然后就把每种的状态的动画分类,这样的话可以选择任何一种动画进行播放。马里奥的每种状态的切换都是用了状态模式来进行,就是走路的状态和站立的状态,每个状态单独处理逻辑。每个状态之间根据情况进行切换,这样简化了逻辑的处理。
func _update(delta):
if status==constants.stand:
stand(delta)
elif status==constants.walk:
walk(delta)
elif status==constants.fall:
fall(delta)
elif status==constants.jump:
jump(delta)
elif status==constants.small2big:
pass
elif status==constants.big2fire:
fireState(delta)
elif status==constants.big2small:
pass
elif status==constants.crouch:
crouch(delta)
elif status==constants.deadJump:
deathJump(delta)
elif status==constants.poleSliding:
poleSliding(delta)
elif status==constants.walkingToCastle:
walkingToCastle(delta)
elif status==constants.sitBottomOfPole:
sitBottomOfPole(delta)
elif status==constants.stop:
pass
elif status==constants.pipeIn:
pipeIn(delta)
pass
elif status==constants.walkInPipe:
walkIntoPipe(delta)
pass
elif status==constants.pipeOut:
pipeOut(delta)
if status!=constants.big2small&&status!=constants.big2fire&&\
status!=constants.small2big:
specialState(delta)
if debug:
update()
pass
复制代码
就拿马里奥走路来说,走路的速度越快,动画变化的越快,这个可以根据移动速度修改动画的播放速度就可以做到,其它的话就是根据按键修改速度。对于转向的可以修改动画的flip_h的值。
func walk(delta):
if xVel>0 || xVel<0:
ani.speed_scale=1+abs(xVel)/constants.marioAniSpeed
if Input.is_action_pressed("ui_action"):
acceleration=constants.runAcceleration
maxXVel=constants.marioRunMaxSpeed
if fire&&allowShoot:
shootFireball(false)
allowShoot=false
else:
acceleration=constants.acceleration
maxXVel=constants.marioWalkMaxSpeed
allowShoot=true
#跳跃
if Input.is_action_pressed("ui_jump"):
yVel=-constants.marioJumpSpeed
gravity=constants.marioJumpGravity
status=constants.jump
playJumpSound()
# print('walk jump')
return
if Input.is_action_pressed("ui_down") &&big:
startCrouch()
return
elif isCrouch and big:
rect=Rect2(Vector2(-11,-30),Vector2(22,60))
position.y-=14
ani.position.y=0
isCrouch=false
if Input.is_action_pressed("ui_left"):
if xVel>0: #反方向
animation("slide")
acceleration=constants.slideFriction
else:
acceleration=constants.acceleration
dir=constants.left
animation('walk')
if xVel>-maxXVel:
xVel-=acceleration*delta
else:
xVel=-maxXVel
elif Input.is_action_pressed("ui_right"):
if xVel<0:
animation("slide")
acceleration=constants.slideFriction
else:
dir=constants.right
acceleration=constants.acceleration
animation('walk')
if xVel<maxXVel:
xVel+=acceleration*delta
else:
xVel=maxXVel
else:
if dir==constants.right:
if xVel>0:
xVel-=acceleration*delta
animation("walk")
else:
ani.speed_scale=1
status=constants.stand
else:
if xVel<0:
xVel+=acceleration*delta
animation("walk")
else:
ani.speed_scale=1
status=constants.stand
position.x+=xVel*delta
if !isOnFloor:
ani.stop()
status=constants.fall
pass
复制代码
马里奥变大或者变小需要对每帧播放时修改动画的位置,这个是因为动画图片大小不一,但是动画的显示是剧中显示的问题。
func _on_ani_frame_changed():
if status==constants.small2big:
# print(ani.frame)
if ani.frame in [0,2,4]:
ani.position.y= 0
else:
ani.position.y=-18
elif ani.animation in throw_animation:
throwAniFinish=true
elif status ==constants.big2small:
if ani.frame in [0]:
ani.position.y= 0
elif ani.frame in [2,4,6,8]:
ani.position.y=20
else:
ani.position.y= 0
pass
if invincible:
shadow.frame=ani.frame
pass # Replace with function body.
func _on_ani_animation_finished():
if status==constants.small2big:
big=true
ani.position.y=0
status=preStatus
rect=Rect2(Vector2(-11,-30),Vector2(22,60))
Game.emit_signal('stateFinish')
elif status==constants.big2small:
hurtInvincible=true
status=preStatus
big=false
fire=false
position.y+=15
aniIndex=0
rect=Rect2(Vector2(-10,-16),Vector2(20,32))
Game.emit_signal('stateFinish')
pass # Replace with function body.
复制代码
在马里奥吃到星星的时候,会不停的变色,这个的话用godot的动画是没办法实现出来,所以我想到了用两个动画的方式,第二个动画不播放,然后根据第一个动画播放啥第二个动画也跟着播放啥,然后不停的更改自身的动画颜色实现不停的变色,前面把同一个类型放在一个数组里,所以只要改变数组下标就可以了。
发射火球的动画需要控制等火球那一帧动画结束后在播放其它动画。其它的内容暂时没想到,想到在补充。
参考资料:
github.com/absolve/god… (项目文件夹mario1)
godotengine.org/
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END