AS3/Flash 开发 - 径向重力(星球模拟中的角色)
AS3/Flash Develop - Radial Gravity (character on planet simulation)
我正在尝试创建一个程序,其中一个角色形状将不断地向行星形状的中心绘制。我已经采纳了以前的建议,使用物理方程来产生所需的效果,但我认为我遗漏了一些,因此它不起作用(我只使用 v^2=u^2+2as)。我是不是把事情复杂化了?我所需要的只是让玩家对象不断地被吸引到行星对象的中心;不需要其他行星物体发挥作用并影响玩家的重力。
编辑:澄清一下,我的问题应该是 "where did I go wrong?"。我现在已经用下面发布的答案解决了这个问题,这些答案存在是因为我不打算尝试以正确的方式实现我想要的。我没有按预期计算实际移动的方向,所以角色无法按预期的方向移动。
这是我的 Main.as:
package
{
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.Event;
import Math
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.*;
/**
* ...
* @author Me
*/
public class Main extends Sprite
{
public var planet1:Planet;
public var character1:Character;
public var initialXVelocity:Number = 0;
public var initialYVelocity:Number = 0;
public var finalXVelocity:Number;
public var finalYVelocity:Number;
public const gravitationalAcceleration:Number = 3;
public var xDistance:Number;
public var yDistance:Number;
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
planet1 = new Planet;
character1 = new Character;
//place entites in position to test note: planet 1 is 100*100 pixels, character 1 is 10*10 pixels
planet1.x = 350;
planet1.y = 250;
character1.y = 100; //295
character1.x = 396; //395
addChild(planet1);
addChild(character1);
//Make sure character has gravity applied constantly
setInterval(playerMove, 1000);
}
public function playerMove():void
{
//Calculate the distance between the character and the planet in terms of x and y coordinate
xDistance = (character1.x + 5) - (planet1.x + 50);
yDistance = (character1.y + 5) - (planet1.y + 50);
//Make sure this distance is a positive value
if (xDistance < 0) {
xDistance = -xDistance;
}
if (yDistance < 0) {
yDistance = -yDistance;
}
//Calculate velocity using physics equation v^2=(u^2)+2as
finalXVelocity = Math.sqrt((initialXVelocity * initialXVelocity) + (2 * gravitationalAcceleration) * xDistance);
finalYVelocity = Math.sqrt((initialYVelocity * initialYVelocity) + (2 * gravitationalAcceleration) * yDistance);
/*trace(initialXVelocity);
trace(gravitationalAcceleration);
trace(xDistance);
trace(finalXVelocity);
trace(initialYVelocity);
trace(gravitationalAcceleration);
trace(yDistance);
trace(finalYVelocity);*/
//Make sure the character is moving towards the centre of the planet at all times by reversing the appropriate velocity once it passes the axis of the centre of the planet
if (planet1.x < character1.x) {
finalXVelocity = -finalXVelocity;
}
if (planet1.y < character1.y) {
finalYVelocity = -finalYVelocity;
}
//Update the current velocity before new velocity is calculated
initialXVelocity = finalXVelocity;
initialYVelocity = finalYVelocity;
//Send the character into the correct direction
character1.x += finalXVelocity;
character1.y += finalYVelocity;
}
}
}
重力通常可以描述为一个加速度常数:
const gravity:Number = 3;
使用横向卷轴之类的东西,您可以在每个刻度中将重力添加到 y 速度:
vy += gravity;
在你的情况下,它实际上是一样的,除了重力不是纯粹地添加到向量 y 上,而是根据朝向行星中心的方向将重力添加到 x 和 y 上,就好像你不断地向地球中心施加推力一样行星中心。所以你只需要找到玩家和行星中心之间的角度:
var angle:Number = Math.atan2(planet.y - player.y, planet.x - player.x);
并且用角度你可以找到重力矢量:
var gravityX:Number = Math.cos(angle) * gravity;
var gravityY:Number = Math.sin(angle) * gravity;
只需将其添加到玩家的向量中即可:
vx += gravityX;
vy += gravityY;
这会导致玩家不断被吸引到地球的中心。当然,在没有任何行星碰撞的情况下,它会一直围绕行星中心旋转。
我正在尝试创建一个程序,其中一个角色形状将不断地向行星形状的中心绘制。我已经采纳了以前的建议,使用物理方程来产生所需的效果,但我认为我遗漏了一些,因此它不起作用(我只使用 v^2=u^2+2as)。我是不是把事情复杂化了?我所需要的只是让玩家对象不断地被吸引到行星对象的中心;不需要其他行星物体发挥作用并影响玩家的重力。
编辑:澄清一下,我的问题应该是 "where did I go wrong?"。我现在已经用下面发布的答案解决了这个问题,这些答案存在是因为我不打算尝试以正确的方式实现我想要的。我没有按预期计算实际移动的方向,所以角色无法按预期的方向移动。
这是我的 Main.as:
package
{
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.Event;
import Math
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.*;
/**
* ...
* @author Me
*/
public class Main extends Sprite
{
public var planet1:Planet;
public var character1:Character;
public var initialXVelocity:Number = 0;
public var initialYVelocity:Number = 0;
public var finalXVelocity:Number;
public var finalYVelocity:Number;
public const gravitationalAcceleration:Number = 3;
public var xDistance:Number;
public var yDistance:Number;
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
planet1 = new Planet;
character1 = new Character;
//place entites in position to test note: planet 1 is 100*100 pixels, character 1 is 10*10 pixels
planet1.x = 350;
planet1.y = 250;
character1.y = 100; //295
character1.x = 396; //395
addChild(planet1);
addChild(character1);
//Make sure character has gravity applied constantly
setInterval(playerMove, 1000);
}
public function playerMove():void
{
//Calculate the distance between the character and the planet in terms of x and y coordinate
xDistance = (character1.x + 5) - (planet1.x + 50);
yDistance = (character1.y + 5) - (planet1.y + 50);
//Make sure this distance is a positive value
if (xDistance < 0) {
xDistance = -xDistance;
}
if (yDistance < 0) {
yDistance = -yDistance;
}
//Calculate velocity using physics equation v^2=(u^2)+2as
finalXVelocity = Math.sqrt((initialXVelocity * initialXVelocity) + (2 * gravitationalAcceleration) * xDistance);
finalYVelocity = Math.sqrt((initialYVelocity * initialYVelocity) + (2 * gravitationalAcceleration) * yDistance);
/*trace(initialXVelocity);
trace(gravitationalAcceleration);
trace(xDistance);
trace(finalXVelocity);
trace(initialYVelocity);
trace(gravitationalAcceleration);
trace(yDistance);
trace(finalYVelocity);*/
//Make sure the character is moving towards the centre of the planet at all times by reversing the appropriate velocity once it passes the axis of the centre of the planet
if (planet1.x < character1.x) {
finalXVelocity = -finalXVelocity;
}
if (planet1.y < character1.y) {
finalYVelocity = -finalYVelocity;
}
//Update the current velocity before new velocity is calculated
initialXVelocity = finalXVelocity;
initialYVelocity = finalYVelocity;
//Send the character into the correct direction
character1.x += finalXVelocity;
character1.y += finalYVelocity;
}
}
}
重力通常可以描述为一个加速度常数:
const gravity:Number = 3;
使用横向卷轴之类的东西,您可以在每个刻度中将重力添加到 y 速度:
vy += gravity;
在你的情况下,它实际上是一样的,除了重力不是纯粹地添加到向量 y 上,而是根据朝向行星中心的方向将重力添加到 x 和 y 上,就好像你不断地向地球中心施加推力一样行星中心。所以你只需要找到玩家和行星中心之间的角度:
var angle:Number = Math.atan2(planet.y - player.y, planet.x - player.x);
并且用角度你可以找到重力矢量:
var gravityX:Number = Math.cos(angle) * gravity;
var gravityY:Number = Math.sin(angle) * gravity;
只需将其添加到玩家的向量中即可:
vx += gravityX;
vy += gravityY;
这会导致玩家不断被吸引到地球的中心。当然,在没有任何行星碰撞的情况下,它会一直围绕行星中心旋转。