我正在制作一个平台游戏。但是我有问题因为每当我按下空格键跳跃时,角色就会陷入半空中。但是,我可以通过按住空格键来解决问题,角色将会降落。
问题发生在位于mainJump()
课程内的Boy
。
我看到很多人通过使用动作时间线来解决问题,但我的主要问题是,无论如何我可以通过使用外部类来解决问题吗?
主要课程
package
{
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.utils.Timer;
import flash.text.*;
public class experimentingMain extends MovieClip
{
var count:Number = 0;
var myTimer:Timer = new Timer(10,count);
var classBoy:Boy;
//var activateGravity:gravity = new gravity();
var leftKey, rightKey, spaceKey, stopAnimation:Boolean;
public function experimentingMain()
{
myTimer.addEventListener(TimerEvent.TIMER, scoreUp);
myTimer.start();
classBoy = new Boy();
addChild(classBoy);
stage.addEventListener(KeyboardEvent.KEY_DOWN, pressTheDamnKey);
stage.addEventListener(KeyboardEvent.KEY_UP, liftTheDamnKey);
}
public function pressTheDamnKey(event:KeyboardEvent):void
{
if (event.keyCode == 37)
{
leftKey = true;
stopAnimation = false;
}
if (event.keyCode == 39)
{
rightKey = true;
stopAnimation = false;
}
if (event.keyCode == 32)
{
spaceKey = true;
stopAnimation = true;
}
}
public function liftTheDamnKey(event:KeyboardEvent):void
{
if (event.keyCode == 37)
{
leftKey = false;
stopAnimation = true;
}
if (event.keyCode == 39)
{
rightKey = false;
stopAnimation = true;
}
if (event.keyCode == 32)
{
spaceKey = false;
stopAnimation = true;
}
}
public function scoreUp(event:TimerEvent):void
{
scoreSystem.text = String("Score : "+myTimer.currentCount);
}
}
}
男生班
package
{
import flash.display.*;
import flash.events.*;
public class Boy extends MovieClip
{
var leftKeyDown:Boolean = false;
var upKeyDown:Boolean = false;
var rightKeyDown:Boolean = false;
var downKeyDown:Boolean = false;
//the main character's speed
var mainSpeed:Number = 5;
//whether or not the main guy is jumping
var mainJumping:Boolean = false;
//how quickly should the jump start off
var jumpSpeedLimit:int = 40;
//the current speed of the jump;
var jumpSpeed:Number = 0;
var theCharacter:MovieClip;
var currentX,currentY:int;
public function Boy()
{
this.x = 600;
this.y = 540;
addEventListener(Event.ENTER_FRAME, boyMove);
}
public function boyMove(event:Event):void
{
currentX = this.x;
currentY = this.y;
if (MovieClip(parent).leftKey)
{
currentX += mainSpeed;
MovieClip(this).scaleX = 1;
}
if (MovieClip(parent).rightKey)
{
currentX -= mainSpeed;
MovieClip(this).scaleX = -1;
}
if (MovieClip(parent).spaceKey)
{
mainJump();
}
this.x = currentX;
this.y = currentY;
}
public function mainJump():void
{
currentY = this.y;
if (! mainJumping)
{
mainJumping = true;
jumpSpeed = jumpSpeedLimit * -1;
currentY += jumpSpeed;
}
else
{
if (jumpSpeed < 0)
{
jumpSpeed *= 1 - jumpSpeedLimit / 250;
if (jumpSpeed > -jumpSpeedLimit/12)
{
jumpSpeed *= -2;
}
}
}
if (jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit)
{
jumpSpeed *= 1 + jumpSpeedLimit / 120;
}
currentY += jumpSpeed;
if (currentY >= stage.stageHeight - MovieClip(this).height)
{
mainJumping = false;
currentY = stage.stageHeight - MovieClip(this).height;
}
}
}
}
答案 0 :(得分:1)
首先,正式化你的代码,消除像'pressTheDamnKey'这样的时髦的东西,它甚至都不能很好地描述这个功能,因为函数不能按键。这是一个事件处理程序,应该命名为keyDownHandler或onKeyDown,没有别的。
其次,除了事件数据的直接关注之外,您很少想要在事件处理程序中进行任何实际工作。而是调用执行实际工作的功能。处理程序处理事件,然后调用执行工作的代码。当你想要的东西 else 能够使小男孩除了enterFrameHandler之外的动画之外,就像鼠标一样,这很好地分离出了关注点。
我可以想象你的跟踪日志很快被“得分”线填满,因为你的计时器每秒发射100次(每个10毫秒)。我会改变这一点,不是在计时器上启动,而是在分数实际发生变化时刷新。
除了意大利面条代码之外,跳跃的问题在于,通过将按键状态保存在变量中并让他不断检查,你可以根据按键是否按下动作。这有几个原因是坏事:1。他不应该向他的环境寻求信息,应该通过他拥有的任何物品或负责告诉他的物品给予他2.它需要你继续按住空格键或者他将停止移动,因为他检查是否被按下(见问题1)。
我将在下面解决所有这些问题,遗漏得分,这完全是另一回事。
package
{
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.*;
// Sprite is preferred if you are not using the timeline
public class Application extends Sprite
{
private var boy:Boy;
public function Application()
{
boy = new Boy();
addChild(boy);
boy.x = 600; // set these here, not in the boy
boy.y = 540;
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler );
}
public function keyDownHandler(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case 32: boy.jump();
break;
case 37: boy.moveLeft();
break;
case 39: boy.moveRight();
break;
default:
// ignored
break;
}
}
public function keyUpHandler(event:KeyboardEvent):void
{
switch(event.keyCode)
{
// ignored for jumping (32)
case 37: // fall through
case 39: boy.stop();
break;
default:
// ignored
break;
}
}
}//class
}//package
package
{
import flash.display.*;
import flash.events.*;
// It is assumed that there is an asset in the library
// that is typed to a Boy, thus it will be loaded onto
// the stage by the owner
public class Boy extends Sprite
{
private var horzSpeed :Number = 0;
private var vertSpeed :Number = 0;
private var floorHeight :Number;
private var jumpHeight :Number;
private var amJumping :Boolean = false;
public function Boy()
{
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
public function moveLeft():void
{
horzSpeed = -1;
}
public function moveRight():void
{
horzSpeed = 1;
}
public function stop():void
{
horzSpeed = 0;
}
public function jump():void
{
if (amJumping) return;
floorHeight = y;
jumpHeight = floorHeight + 20;
vertSpeed = 2;
amJumping = true;
animateJump();
}
private function enterFrameHandler(event:Event):void
{
animate();
}
private function animate():void
{
x += horzSpeed;
if( amJumping )
{
animateJump();
}
}
// Doing a simple version for this example.
// If you want an easier task of jumping with gravity,
// I recommend you employ Greensock's superb
// TweenLite tweening library.
private function animateJump():void
{
y += vertSpeed;
if( y >= jumpHeight )
{
y = jumpHeight;
vertSpeed = -2;
}
else if( y <= floorHeight )
{
y = floorHeight;
amJumping = false;
}
}
}//class
}//package
另一种接近这种方式的方法,也许是长期更好的方式,是男孩甚至不负责自己移动。相反,你会在父母,他的主人或一些特殊的Animator类中处理这个问题,该类负责按计划制作动画。在这个更加封装的范例中,这个男孩只负责根据外面的世界更新自己内部的外观,告诉他发生了什么。他不再处理内部跳跃,而是负责做他所拥有的动画,比如他的胳膊和腿。
答案 1 :(得分:0)
你有一个mainJumping
变量只在跳转运行时才为真。为什么不用它?
if (MovieClip(parent).spaceKey || mainJumping)
{
mainJump();
}