Creation of a Flash artillery game using Box2D – part 2: removing bullets
2009-10-18 00:00:00 来源:WEB开发网Next step is assign the class to every new bullet and periodically check for bullet age and eventually remove it.
package {
import flash.display.Sprite;
import flash.events.Event;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import General.Input;
import flash.events.MouseEvent;
public class HelloWorld extends Sprite {
public var m_world:b2World;
public var pixels_in_a_meter:int=30;
public var bodyDef:b2BodyDef;
public var boxDef:b2PolygonDef;
public var m_input:Input;
public var xspeed:int=0;
public var bazooka:zooka=new zooka();
public var bazooka_angle:Number;
public var m_contactListener=new b2ContactListener();
// defining the power of the bazooka
public var power:int=1;
// flag to determine if I am charging the bazooka
// 0 = not charging
// 1 = positive charge
// -1 = negative charge
public var charging:int=0;
var body:b2Body;
public function HelloWorld() {
addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100.0, -100.0);
worldAABB.upperBound.Set(100.0, 100.0);
var gravity:b2Vec2=new b2Vec2(0.0,10.0);
var doSleep:Boolean=true;
m_world=new b2World(worldAABB,gravity,doSleep);
var m_sprite:Sprite;
m_sprite = new Sprite();
addChild(m_sprite);
var dbgDraw:b2DebugDraw = new b2DebugDraw();
var dbgSprite:Sprite = new Sprite();
m_sprite.addChild(dbgSprite);
dbgDraw.m_sprite=m_sprite;
dbgDraw.m_drawScale=30;
dbgDraw.m_alpha=1;
dbgDraw.m_fillAlpha=0.5;
dbgDraw.m_lineThickness=1;
dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit;
m_world.SetDebugDraw(dbgDraw);
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
square_tile(250,395,500,10);
hero(100,370,20,40);
//
// adding the contact listener
m_world.SetContactListener(m_contactListener);
//
// Box2D input class - why should I bother making my one?
m_sprite = new Sprite();
addChild(m_sprite);
// input
m_input=new Input(m_sprite);
addChild(bazooka);
bazooka.gotoAndStop(1);
// now we don't shoot when the player clicks the mouse
// but we charge bazooka's power while the mouse is pressed
// and release the bullet when it's released
stage.addEventListener(MouseEvent.MOUSE_UP, shoot);
stage.addEventListener(MouseEvent.MOUSE_DOWN,charge);
}
public function charge(event:Event) {
// I always start with positive charging
charging=1;
}
public function shoot(event:Event) {
// reset charging
charging=0;
bodyDef = new b2BodyDef();
bodyDef.position.Set((bazooka.x+(bazooka.width+3)*Math.cos(bazooka_angle))/pixels_in_a_meter, (bazooka.y+(bazooka.width+3)*Math.sin(bazooka_angle))/pixels_in_a_meter);
boxDef = new b2PolygonDef();
boxDef.SetAsBox(10/pixels_in_a_meter,10/pixels_in_a_meter);
boxDef.friction=0.3;
boxDef.density=1;
// the bullet now has its own class
bodyDef.userData = new bullet();
// giving the bullet a name... let's say "bullet"...
bodyDef.userData.name="bullet";
body=m_world.CreateBody(bodyDef);
body.CreateShape(boxDef);
body.SetMassFromShapes();
// apply the impulse according to the power
// that "/4" is just a setting to have decent gameplay
body.ApplyImpulse(new b2Vec2(Math.cos(bazooka_angle)*power/4, Math.sin(bazooka_angle)*power/4),body.GetWorldCenter());
// resetting the power
power=1;
// updating bazooka clip
bazooka.gotoAndStop(1);
}
public function square_tile(px:int,py:int,w:int,h:int) {
bodyDef = new b2BodyDef();
bodyDef.position.Set(px/pixels_in_a_meter, py/pixels_in_a_meter);
boxDef = new b2PolygonDef();
boxDef.SetAsBox(real_pixels(w), real_pixels(h));
boxDef.friction=0.3;
boxDef.density=0;
body=m_world.CreateBody(bodyDef);
body.CreateShape(boxDef);
body.SetMassFromShapes();
}
public function hero(px:int, py:int, w:int, h:int) {
bodyDef = new b2BodyDef();
bodyDef.position.Set(px/pixels_in_a_meter, py/pixels_in_a_meter);
boxDef = new b2PolygonDef();
boxDef.SetAsBox(real_pixels(w), real_pixels(h));
boxDef.density=1.0;
boxDef.friction=0.3;
boxDef.restitution=0.2;
bodyDef.userData = new Sprite();
bodyDef.userData.name="Player";
body=m_world.CreateBody(bodyDef);
body.SetBullet(true);
body.CreateShape(boxDef);
//
var ground_sensor:b2PolygonDef = new b2PolygonDef();
ground_sensor.isSensor=true;
ground_sensor.userData="groundsensor";
ground_sensor.SetAsOrientedBox(10/pixels_in_a_meter,5/pixels_in_a_meter,new b2Vec2(0,27/pixels_in_a_meter), 0);
body.CreateShape(ground_sensor);
//
body.SetMassFromShapes();
}
public function real_pixels(n:int) {
return (n/pixels_in_a_meter/2);
}
public function Update(e:Event):void {
m_world.Step(1/30, 10);
xspeed=0;
for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
if (bb.GetUserData()!=null) {
// I know my body is "something", now I have to perform
// different actions according to body's name... "Player" or "bullet"
switch (bb.m_userData.name) {
// same as before
case "Player" :
if (Input.isKeyDown(39)) {// right arrow
xspeed=3;
} else if (Input.isKeyDown(37)) {// left arrow
xspeed=-3;
}
if (Input.isKeyDown(38)) {// up arrow
if (m_contactListener.can_jump()) {// checking if the hero can jump
bb.ApplyImpulse(new b2Vec2(0.0, -1.0), bb.GetWorldCenter());
}
}
if (xspeed) {
bb.WakeUp();
bb.m_linearVelocity.x=xspeed;
}
bb.m_sweep.a=0;
bazooka.x=bb.m_userData.x=bb.GetPosition().x*30;
bazooka.y=bb.m_userData.y=bb.GetPosition().y*30;
var dist_x=bazooka.x-mouseX;
var dist_y=bazooka.y-mouseY;
bazooka_angle=Math.atan2(- dist_y,- dist_x);
bazooka.rotation=bazooka_angle*57.2957795;
break;
case "bullet" :
// checking if I have to remove the bullet
if (bb.m_userData.has_to_be_removed()) {
// removing the bullet
bb.m_userData=null;
m_world.DestroyBody(bb);
}
break;
}
}
}
// If I am charging the bazooka (I am holding the mouse)
if (charging!=0) {
// update the power
power+=charging;
// if the power ran out of range...
// (I assume max power is 30 because there are 30 frames in the bazooka animation
if (power>30||power<1) {
// invert the power
charging*=-1;
// update the power again
power+=charging;
}
// show the correct bazooka frame
bazooka.gotoAndStop(power);
}
Input.update();
}
}
}
And this is the result… same as Creation of a Flash artillery game using Box2D but boxes disappear after 10 seconds.
本文示例源代码或素材下载
更多精彩
赞助商链接