プレーヤーが矢印または WASD を使用してステージの周りのムービークリップ (_character) を制御するゲームを作成しています。ステージには、衝突検出機能を備えた四角形/ボックスがあります。さらに、50 ピクセルのステージ境界。
_character には 5 つのキー フレームがあり、それぞれにアニメーションがあり、4 つの方向ボタンが押されたときに再生され、キーが押されていないときに赤い固定アニメーションが再生されます。キャラクターを動かしている間、体と頭は動かさず、脚を動かします。以下の例
ただし、私の問題は、ムービー クリップがステージのさまざまな領域で上下に揺れ、他の領域では問題ないことです。
以下の SWF の例では、キャラクターの口と肩がステージの周りで上下に揺れているのがわかりますが、不思議なことに、プレイ エリアの下部では正常に戻っています。(右下の 2 つのボックスの間を除く)
これは、すべてのフレームをフィーチャーした埋め込み SWF です。変更点は体色と目と足の可動くらいです。頭と肩が上下に揺れません。
これが何であるか、またはなぜそれが起こっているのか誰にも分かりませんか? バウンス/ボビング アニメーションを作成するフレームの位置がずれている場合に備えて、キャラクターの SWF を 3 回チェックしましたが、それらはすべて正しいので、SWF はそうすべきではありません。
いくつかのボックスを削除すると、一部の領域でボビング効果が停止しますが、他の領域では元に戻ります。時々、ボックスに触れるとボブし、ボックスの他の側面には触れないことがあります(?) 奇妙なことに、プレイエリアの下部を押し下げると、ボブが元に戻ります。もう 1 つの SWF では、ステージの下部は、ムービークリップが跳ねたり跳ねたりしなかった数少ない領域の 1 つでした。
すべてのボックスを削除すると、プレイ可能領域の下部を押し下げた場合を除いて、ボビングは停止します。しかし、その片側だけがボビングを引き起こします。ステージの境界も削除すると、ムービークリップが反応するものが何もないため、ボビングが完全に停止します。
現在のコード
Rookies ゲーム/Application クラスは、levelOne をステージに配置するためのレベル スイッチャーとして使用されます。
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
[SWF(width="650", height="450", backgroundColor="#FFFFFF", frameRate="60")]
public class RookiesGame extends Sprite
{
private var _levelOne:LevelOne;
//public static var gameMute:Boolean = false;
public function RookiesGame()
{
_levelOne = new LevelOne(stage);
stage.addChild(_levelOne);
stage.addEventListener("levelOneComplete",levelTwoSwitchHandler);
}
private function levelTwoSwitchHandler(event:Event):void
{
}
}
}
レベル 1には、ほとんどのコードと作業の大部分が含まれています。
package
{
//import statements
public class LevelOne extends Sprite
{
//Declare the variables to hold the game objects
private var _character:Character = new Character();
private var _background:Background = new Background();
private var _box1:Box = new Box();
//Other box vars
//A variable to store the reference to the stage from the application class
private var _stage:Object;
//Control System
private var _bUp:Boolean = false;
private var _bDown:Boolean = false;
private var _bLeft:Boolean = false;
private var _bRight:Boolean = false;
public function LevelOne(stage:Object)
{
_stage = stage;
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(event:Event):void
{
startGame();
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function startGame():void
{
//Add them to stage.
addGameObjectToLevel(_background, 0, 0);
addGameObjectToLevel(_box1, 300, 200);
//Other boxes added to level
//Add character
this.addChild(_character);
_character.x = 300;
_character.y = 50;
_character.gotoAndStop(1);
playGame();
}
private function playGame():void
{ //EVENT LISTENERS////////////////////////
_stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(event:Event):void
{
_character.accelerationX = 0;
_character.accelerationY = 0;
_character.friction = 0.94;
var _updown:Boolean=Boolean(!(_bUp==_bDown));
var _leftright:Boolean=Boolean(!(_bLeft==_bRight));
if (!_updown && !_leftright)
{ // not moving anywhere
_character.gotoAndStop(1);
_character.accelerationX = 0;
_character.accelerationY = 0;
_character.friction = 0.94;
_character.vy=0;
_character.vx=0;
}
else
{
if (_bUp)
{
_character.accelerationY = -0.5;
_character.gotoAndStop(2);
}
else if (_bDown)
{
_character.accelerationY = 0.5;
_character.gotoAndStop(3);
}
if (_bLeft)
{
_character.accelerationX = -0.5;
_character.gotoAndStop(4);
}
else if (_bRight)
{
_character.accelerationX = 0.5;
_character.gotoAndStop(5);
}
}
//Apply friction
_character.vx *= _character.friction;
_character.vy *= _character.friction;
//Apply acceleration
_character.vx += _character.accelerationX;
_character.vy += _character.accelerationY;
//Limit the speed
if (_character.vx > _character.speedLimit)
{
_character.vx = _character.speedLimit;
}
if (_character.vx < -_character.speedLimit)
{
_character.vx = -_character.speedLimit;
}
if (_character.vy > _character.speedLimit)
{
_character.vy = _character.speedLimit;
}
if (_character.vy < -_character.speedLimit)
{
_character.vy = -_character.speedLimit;
}
//Force the velocity to zero after it falls below 0.1
if (Math.abs(_character.vx) < 0.1)
{
_character.vx = 0;
}
if (Math.abs(_character.vy) < 0.1)
{
_character.vy = 0;
}
//Move the character
_character.x += _character.vx;
_character.y += _character.vy;
checkStageBoundaries(_character);
//Box Collisions
Collision.block(_character,_box1);
Other box collisions
}
private function checkStageBoundaries(gameObject:MovieClip):void
{
if (gameObject.x < 50)
{
gameObject.x = 50;
}
if (gameObject.y < 50)
{
gameObject.y = 50;
}
if (gameObject.x + gameObject.width > _stage.stageWidth - 50)
{
gameObject.x = _stage.stageWidth - gameObject.width - 50;
}
if (gameObject.y + gameObject.height > _stage.stageHeight - 50)
{
gameObject.y = _stage.stageHeight - gameObject.height - 50;
}
}
public function replay():void
{
_stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
startGame();
}
private function keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == 65 )
{
_bLeft=true;
}
else if (event.keyCode == Keyboard.RIGHT || event.keyCode == 68)
{
_bRight=true;
}
else if (event.keyCode == Keyboard.UP || event.keyCode == 87 )
{
_bUp=true;
}
else if (event.keyCode == Keyboard.DOWN || event.keyCode == 83)
{
_bDown=true;
}
if (event.keyCode == Keyboard.ENTER)
{
replay();
}
}
private function keyUpHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT
|| event.keyCode == 65 || event.keyCode == 68)
{
_bLeft=false;
_bRight=false;
}
else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP
|| event.keyCode == 87 || event.keyCode == 83 )
{
_bUp=false;
_bDown=false;
}
}
private function addGameObjectToLevel(gameObject:Sprite, xPos:int, yPos:int):void
{
this.addChild(gameObject);
gameObject.x = xPos;
gameObject.y = yPos;
}
}
}
_character はCharacter Classのインスタンスです。
SWF には 5 つのキー フレームがあり、それぞれの中にアニメーションがあり、4 つの方向ボタンが押されたときに再生されます。また、何も押されていないときに赤い固定アニメーションが再生されます。
package
{
import flash.display.MovieClip;
import flash.display.DisplayObject
[Embed(source="../swfs/characterResource.swf", symbol="Character")]
public class Character extends MovieClip
{
//Public properties
public var vx:Number = 0;
public var vy:Number = 0;
public var accelerationX:Number = 0;
public var accelerationY:Number = 0;
public var speedLimit:Number = 4;
public var friction:Number = 0.94;
public function Character()
{
}
}
}
BoxクラスとBackgroundクラスは同じで、スプライトを表示するだけです。グリッドの背景は単一の画像であることに注意してください。ゲームはタイルベースではありません。.
衝突クラス。_character がボックスと衝突すると、Collision.block 関数が呼び出されます。
package
{
import flash.display.Sprite;
public class Collision
{
static public var collisionSide:String = "";
public function Collision()
{
}
static public function block(r1:Sprite, r2:Sprite):void
{
//Calculate the distance vector
var vx:Number
= (r1.x + (r1.width / 2))
- (r2.x + (r2.width / 2));
var vy:Number
= (r1.y + (r1.height / 2))
- (r2.y + (r2.height / 2));
//Check whether vx
//is less than the combined half widths
if(Math.abs(vx) < r1.width / 2 + r2.width / 2)
{
//A collision might be occurring! Check
//whether vy is less than the combined half heights
if(Math.abs(vy) < r1.height / 2 + r2.height / 2)
{
//A collision has ocurred!
//Find out the size of the overlap on both the X and Y axes
var overlap_X:Number
= r1.width / 2
+ r2.width / 2
- Math.abs(vx);
var overlap_Y:Number
= r1.height / 2
+ r2.height / 2
- Math.abs(vy);
//The collision has occurred on the axis with the
//*smallest* amount of overlap. Let's figure out which
//axis that is
if(overlap_X >= overlap_Y)
{
//The collision is happening on the X axis
//But on which side? _v0's vy can tell us
if(vy > 0)
{
collisionSide = "Top";
//Move the rectangle out of the collision
r1.y = r1.y + overlap_Y;
}
else
{
collisionSide = "Bottom";
//Move the rectangle out of the collision
r1.y = r1.y - overlap_Y;
}
}
else
{
//The collision is happening on the Y axis
//But on which side? _v0's vx can tell us
if(vx > 0)
{
collisionSide = "Left";
//Move the rectangle out of the collision
r1.x = r1.x + overlap_X;
}
else
{
collisionSide = "Right";
//Move the rectangle out of the collision
r1.x = r1.x - overlap_X;
}
}
}
else
{
//No collision
collisionSide = "No collision";
}
}
else
{
//No collision
collisionSide = "No collision";
}
}
}
}
どんな助けでも大歓迎です。
また、迷路の隙間を横切るときのムービークリップのジャンプ/身震いについても質問しています。その情報のいずれかがあなたに役立つか、それに対する解決策も知っているほど賢いなら、質問はここにあります