第一个问题! NPC 步行循环随机化器按预期工作(边界确实需要调整),但不播放嵌套的步行动画? (AS3)

Posted

技术标签:

【中文标题】第一个问题! NPC 步行循环随机化器按预期工作(边界确实需要调整),但不播放嵌套的步行动画? (AS3)【英文标题】:First question! NPC walk-cycle randomizer is working as intended (boundaries do need tweaking), but not playing the nested walking animations? (AS3) 【发布时间】:2020-01-25 10:45:42 【问题描述】:

差不多,我认为步行动画不适用于 switch 语句?这就是它的样子,但随机发生器本身工作正常。我想做的是重写 mc 的工作代码,但是用 switch 语句中的 case(选择的随机行走方向)替换关键输入,并将重写的代码单独插入 NPC 的大脑 (roshi)。

我设置代码的方式是 NPC“roshi”是舞台上的电影剪辑。里面是单独的电影剪辑,每个动画剪辑都有每个行走动画的帧,但它们不会播放(例如 roshiRightStand、roshiRightWalk 等)。它总是卡在选定的帧上,无论我如何弄乱代码、括号或布尔值,它都不会真正进入影片剪辑。也许我没有正确或根本没有声明或嵌套某些东西?动画是嵌套在另一个动画剪辑中的动画剪辑中的帧,并且名称似乎在属性中匹配?不太确定如何声明它,但在某些时候我相信我可能已经让整个事情正常工作并且把它搞砸了。如果有帮助,请留下我旧的剩余代码?任何输入将不胜感激!学得还算快。 :)

*带有错误的代码(已删除):https://textuploader.com/108de

*代码清理整理:https://textuploader.com/108lw

*游戏上传(按原样反映代码;可在您的浏览器上使用插件播放):https://www.newgrounds.com/dump/item/e06224a5f9fd5645ce5a4604173f8bbd?fbclid=IwAR3HJdXMXEqxUN5TH2xaDvV82QBDmI0ewnVej1EQJFkZLb3RYuEK0dvMz74

import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.display.Stage;
import flash.events.MouseEvent;


mc.gotoAndStop("standingRight");
toggle_btn.stop();


var played:Boolean=false;
var mySound:Sound = new MySound();
var myChannel:SoundChannel = new SoundChannel();

var rightPressed:Boolean = new Boolean(false);
var leftPressed:Boolean = new Boolean(false);
var upPressed:Boolean = new Boolean(false);
var downPressed:Boolean = new Boolean(false);
var mcSpeed:Number = 10;

var roshiTimer:Number = 0; //random roshi-cycle duration between 0-25
var roshiDuration:Number = Math.random() * 25;
var roshiFacing:Number = Math.floor(Math.random() * 4); //random # bwt 0-3 (ex. 4 is rounded down to 3)
var roshiSpeed:Number = 3; //roshi's walk speed


toggle_btn.addEventListener(MouseEvent.CLICK, togglePlay);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
stage.addEventListener(Event.ENTER_FRAME, gameLoop);


function togglePlay(event:MouseEvent):void

   (!played)? played = true : played = false;
   (played)? myChannel=mySound.play():SoundMixer.stopAll();

   (played)? toggle_btn.gotoAndStop(2):toggle_btn.gotoAndStop(1);
    myChannel.addEventListener(Event.SOUND_COMPLETE,soundCompleted);

function soundCompleted(event:Event):void

	played = false;
	toggle_btn.gotoAndStop(1);



function keyDownHandler(keyEvent:KeyboardEvent):void

   if(keyEvent.keyCode == Keyboard.RIGHT)
   
	   rightPressed = true;
   
   else if(keyEvent.keyCode == Keyboard.LEFT)
   
	   leftPressed = true;
   
   else if(keyEvent.keyCode == Keyboard.DOWN)
   
	   downPressed = true;
   
   else if(keyEvent.keyCode == Keyboard.UP)
   
	   upPressed = true;
   


function keyUpHandler(keyEvent:KeyboardEvent):void

   if(keyEvent.keyCode == Keyboard.RIGHT)
   
	   rightPressed = false;
	   mc.gotoAndStop("standingRight");
   
   else if(keyEvent.keyCode == Keyboard.LEFT)
   
	leftPressed = false;
	mc.gotoAndStop("standingLeft");
   
   else if (keyEvent.keyCode == Keyboard.DOWN)
   
       downPressed = false;
	   mc.gotoAndStop("standingDown");
   
   else if(keyEvent.keyCode == Keyboard.UP)
   
	   upPressed = false;
	   mc.gotoAndStop("standingUp");
   



function gameLoop(loopEvent:Event):void 
  
	//MC's Movement Controls
    if(rightPressed && mc.currentLabel !="walkingRight" && upPressed == false && downPressed == false)
	 
       mc.gotoAndStop("walkingRight");
    
    if(rightPressed && mc.currentLabel =="walkingRight")
    
	   if(mc.x < 800)
	   
          mc.x += mcSpeed;
	   

	   else if (backenvironment.x > -650) //right world borderwall
	   
	   backenvironment.x -= mcSpeed; 
	   frontenvironment.x -= mcSpeed;
	   
     
	
    if(leftPressed && mc.currentLabel !="walkingLeft" && upPressed == false && downPressed == false)
    
       mc.gotoAndStop("walkingLeft");
    
    if(leftPressed && mc.currentLabel =="walkingLeft")
    
	   if(mc.x > 200)
	   
          mc.x -= mcSpeed;
	   
	   else if (backenvironment.x < -130) //left world borderwall
	   
	      backenvironment.x += mcSpeed;
	      frontenvironment.x += mcSpeed;
	   
    
	
    if(upPressed && mc.currentLabel != "walkingUp" && rightPressed == false && leftPressed == false)  
	
       mc.gotoAndStop("walkingUp");
    
    if(upPressed && mc.currentLabel == "walkingUp")
    
	   if(mc.y > 200) //og 200
	   
          mc.y -= mcSpeed;10
       
	   else if (backenvironment.y < -10) //top world borderwall
	   
	      backenvironment.y += mcSpeed;
	      frontenvironment.y += mcSpeed;
	   
	
	   
    if(downPressed && mc.currentLabel != "walkingDown" && rightPressed == false && leftPressed == false)
    
       mc.gotoAndStop("walkingDown");
    
	
    if (downPressed && mc.currentLabel == "walkingDown")
    
	   if(mc.y < 485) //og 568 LESS MOVES MC UP CAMERA
	   
          mc.y += mcSpeed;
       
	   else if (backenvironment.y > -577) //bottom world borderwall og-577
       
		   backenvironment.y -= mcSpeed;
		   frontenvironment.y -= mcSpeed;
       
   


   if(roshiTimer < roshiDuration)
   
      switch(roshiFacing) //x=horozontal y=vertical +=right/up -=left/down
      
			case 0 :
			roshi.gotoAndStop("roshiUpWalk");
			//roshi.addEventListener(Event.ENTER_FRAME)
			roshi.y -= roshiSpeed;
			break;
		
			case 1 :
			roshi.gotoAndStop("roshiDownWalk");
			roshi.y += roshiSpeed;
			break;
			
			case 2 :
			roshi.gotoAndStop("roshiLeftWalk");
			roshi.x -= roshiSpeed;
			break;
			
			case 3 :
			roshi.gotoAndStop("roshiRightWalk");
			roshi.x += roshiSpeed;
			break;
	  
      roshiTimer ++;	
   
   
   if(roshiTimer > roshiDuration)
   
      roshiDuration = Math.random() * 25; //25
      roshiFacing = Math.floor(Math.random() * 4); //4
      roshiTimer = 0; //greater than 0
   

~由用户 Organis 解决。

import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.display.Stage;
import flash.events.MouseEvent;


mc.gotoAndStop("standingRight");
toggle_btn.stop();


var played:Boolean=false;
var mySound:Sound = new MySound();
var myChannel:SoundChannel = new SoundChannel();

var rightPressed:Boolean = new Boolean(false);
var leftPressed:Boolean = new Boolean(false);
var upPressed:Boolean = new Boolean(false);
var downPressed:Boolean = new Boolean(false);
var mcSpeed:Number = 10;

var roshiTimer:int = 0;
var roshiDuration:int = 0;
var roshiFacing:int = 0;
var roshiSpeed:Number = 3

addEventListener(Event.ENTER_FRAME, onRoshi);
toggle_btn.addEventListener(MouseEvent.CLICK, togglePlay);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
stage.addEventListener(Event.ENTER_FRAME, gameLoop);


function togglePlay(event:MouseEvent):void

   (!played)? played = true : played = false;
   (played)? myChannel=mySound.play():SoundMixer.stopAll();

   (played)? toggle_btn.gotoAndStop(2):toggle_btn.gotoAndStop(1);
    myChannel.addEventListener(Event.SOUND_COMPLETE,soundCompleted);

function soundCompleted(event:Event):void

	played = false;
	toggle_btn.gotoAndStop(1);



function keyDownHandler(keyEvent:KeyboardEvent):void

   if(keyEvent.keyCode == Keyboard.RIGHT)
   
	   rightPressed = true;
   
   else if(keyEvent.keyCode == Keyboard.LEFT)
   
	   leftPressed = true;
   
   else if(keyEvent.keyCode == Keyboard.DOWN)
   
	   downPressed = true;
   
   else if(keyEvent.keyCode == Keyboard.UP)
   
	   upPressed = true;
   


function keyUpHandler(keyEvent:KeyboardEvent):void

   if(keyEvent.keyCode == Keyboard.RIGHT)
   
	   rightPressed = false;
	   mc.gotoAndStop("standingRight");
   
   else if(keyEvent.keyCode == Keyboard.LEFT)
   
	leftPressed = false;
	mc.gotoAndStop("standingLeft");
   
   else if (keyEvent.keyCode == Keyboard.DOWN)
   
       downPressed = false;
	   mc.gotoAndStop("standingDown");
   
   else if(keyEvent.keyCode == Keyboard.UP)
   
	   upPressed = false;
	   mc.gotoAndStop("standingUp");
   



function gameLoop(loopEvent:Event):void 
  
	
    if(rightPressed && mc.currentLabel !="walkingRight" && upPressed == false && downPressed == false)
	 
       mc.gotoAndStop("walkingRight");
    
    if(rightPressed && mc.currentLabel =="walkingRight")
    
	   if(mc.x < 800)
	   
          mc.x += mcSpeed;
	   

	   else if (backenvironment.x > -650) 
	   
	   backenvironment.x -= mcSpeed; 
	   frontenvironment.x -= mcSpeed;
	   
     
	
    if(leftPressed && mc.currentLabel !="walkingLeft" && upPressed == false && downPressed == false)
    
       mc.gotoAndStop("walkingLeft");
    
    if(leftPressed && mc.currentLabel =="walkingLeft")
    
	   if(mc.x > 200)
	   
          mc.x -= mcSpeed;
	   
	   else if (backenvironment.x < -130)
	   
	      backenvironment.x += mcSpeed;
	      frontenvironment.x += mcSpeed;
	   
    
	
    if(upPressed && mc.currentLabel != "walkingUp" && rightPressed == false && leftPressed == false)  
	
       mc.gotoAndStop("walkingUp");
    
    if(upPressed && mc.currentLabel == "walkingUp")
    
	   if(mc.y > 200) 
	   
          mc.y -= mcSpeed;10
       
	   else if (backenvironment.y < -10) 
	   
	      backenvironment.y += mcSpeed;
	      frontenvironment.y += mcSpeed;
	   
	
	   
    if(downPressed && mc.currentLabel != "walkingDown" && rightPressed == false && leftPressed == false)
    
       mc.gotoAndStop("walkingDown");
    
	
    if (downPressed && mc.currentLabel == "walkingDown")
    
	   if(mc.y < 485) 
	   
          mc.y += mcSpeed;
       
	   else if (backenvironment.y > -577) 
       
		   backenvironment.y -= mcSpeed;
		   frontenvironment.y -= mcSpeed;
       
   




var RF:Array = 
[
    "roshiUpWalk", "roshiDownWalk",
    "roshiLeftWalk", "roshiRightWalk",
];

var RX:Array = [0, 0, -1, 1];
var RY:Array = [-1, 1, 0, 0];

function onRoshi(e:Event):void

      roshiTimer ++;	

      if (roshiTimer > roshiDuration)
    
        roshiDuration = 10 + Math.random() * 25;
        roshiTimer = 0;
		
        while (Roshi.currentLabel == RF[roshiFacing])
        
            roshiFacing = Math.random() * 4;
        

        Roshi.gotoAndStop(RF[roshiFacing]);
    

    Roshi.x += RX[roshiFacing] * roshiSpeed;
    Roshi.y += RY[roshiFacing] * roshiSpeed;

【问题讨论】:

对于平台内缺少代码 sn-ps,我深表歉意,我将它们链接起来,因为这样更容易阅读整个引擎。我将隔离有问题的 sn-p,但它在 gameLoop 中是一个相当长的块。 如果不考虑您要求帮助您调试相当大的代码这一事实,最后一个只是注释行,根本不应该工作。 并没有真正回答我的问题。我让我的错误可见,它们不在编译器上运行。所有的代码都是可见的,我提到这个问题是在循环中被隔离的; NPC“roshi”在给定的代码中也非常清楚地标记。代码运行良好,是嵌套在舞台上的 npc 电影片段中的电影片段行走动画。 如果您至少可以为我指明正确的方向,那么您将成为救命稻草。修剪时它没有那么大,我发誓哈哈。有什么建议吗? 我会修剪它并上传一个更清晰的链接以使其更容易,感谢您的建议。 【参考方案1】:

好吧,我们还是试试吧。将其与 Roshi 图形一起放入单独的项目中。您的代码与此代码之间的主要区别在于,我不会在每一帧都触发 Roshi.gotoAndStop,只是在 Roshi 改变方向时触发一次。

// Integers, because you don't have to round them.
var roshiTimer:int = 0;
var roshiDuration:int = 0;
var roshiFacing:int = 0;
var roshiSpeed:Number = 3;

addEventListener(Event.ENTER_FRAME, onRoshi);

// Let's do this instead of switch.
var RF:Array = [
    "roshiUpWalk", "roshiDownWalk",
    "roshiLeftWalk", "roshiRightWalk",
];

var RX:Array = [0, 0, -1, 1];
var RY:Array = [-1, 1, 0, 0];

function onRoshi(e:Event):void

    roshiTimer++;

    if (roshiTimer > roshiDuration)
    
        roshiDuration = 10 + Math.random() * 25;
        roshiTimer = 0;

        // Let's make Roshi ALWAYS change direction
        // without occasionally proceeding to the same one.
        while (Roshi.currentLabel == RF[roshiFacing])
        
            roshiFacing = Math.random() * 4;
        

        Roshi.gotoAndStop(RF[roshiFacing]);
    

    Roshi.x += RX[roshiFacing] * roshiSpeed;
    Roshi.y += RY[roshiFacing] * roshiSpeed;

【讨论】:

就是这样,这个疯子找到了一个实用的替代方案。你是个英雄,伙计;多谢!!!我会记下你的用户名,并在来源/学分中给予适当的信任。 @CodeBlue 我很高兴我的猜测有所帮助:)

以上是关于第一个问题! NPC 步行循环随机化器按预期工作(边界确实需要调整),但不播放嵌套的步行动画? (AS3)的主要内容,如果未能解决你的问题,请参考以下文章

平台游戏中的 Sprite Kit NPC 随机移动

For 循环在 Django、HTML 中无法按预期工作

当 NPC 向左或向右走时,如何使动画匹配?

NPC随机响应算法

返回到第一个循环

html 生成随机NPC名称