`
hgfghww6
  • 浏览: 42147 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用Flex和Actionscript开发Flash游戏――碰撞检测

 
阅读更多

  这一部分,我们加入碰撞检测,让玩家能够真正的攻击敌机。
  顾名思义,碰撞检测就是能够探测两个物体碰撞,并且做出相应的反应。第五部分里,我们的飞船已
  经能够将子弹射向敌机。唯一的问题就是子弹穿过了敌机。这部分中,我们要用代码实现碰撞检测,将敌
  机击落。
  表面上看碰撞检测很简单,但是实际上,这是一个非常难实现的概念。你能发现有的书整本都在讲述
  二维物体间及三维物体间的相交性。幸好,我们使用的碰撞检测比较简单。每一个画面上的物体都拥有一
  个矩形包围盒,用来进行碰撞检测。这些矩形包围盒与下面图像的长宽一致。当矩形重叠时,我们就认为
  是碰撞了。
  最好是将图片裁剪到没有空白边,以便更加精确的进行碰撞检测。例如:上图就比下图更优。下图
  的空白部分同样会被用于碰撞检测。
  [img[/img]
  接下来,让我们看一下GameObject类的改变:
  GameObject.as package
  {
  import flash.display.*;
  import flash.events.*;
  import flash.geom.*;
  /*
  The base class for all objects in the game.
  */
  public class GameObject
  {
  // object position
  public var position:Point = new Point(0, 0);
  // higher zOrder objects are rendered on top of lower ones
  public var zOrder:int = 0;
  // the bitmap data to display 
  public var graphics:GraphicsResource = null;
  // true if the object is active in the game
  public var inuse:Boolean = false;
  public var collisionArea:Rectangle;
  public var collisionName:String = CollisionIdentifiers.NONE; 
  public function get CollisionArea():Rectangle
  {
  return new Rectangle(position.x, position.y, collisionArea.width, collisionArea.height);
  } 
  public function GameObject()
  {
  }
  public function startupGameObject(graphics:GraphicsResource, position:Point, z:int = 0):void
  {
  if (!inuse)
  {
  this.graphics = graphics;
  this.zOrder = z;
  this.position = position.clone();
  this.inuse = true;
  GameObjectManager.Instance.addGameObject(this);
  setupCollision();
  }
  }
  public function shutdown():void
  {
  if (inuse)
  { 
  graphics = null;
  inuse = false;
  GameObjectManager.Instance.removeGameObject(this);
  }
  }
  public function copyToBackBuffer(db:BitmapData):void
  {
  db.copyPixels(graphics.bitmap, graphics.bitmap.rect, position, graphics.bitmapAlpha, new 
  Point(0, 0), true);
  }
  public function enterFrame(dt:Number):void
  {
  }
  public function click(event:MouseEvent):void
  {
  }
  public function mouseDown(event:MouseEvent):void
  {
  }
  public function mouseUp(event:MouseEvent):void
  {
  }
  public function mouseMove(event:MouseEvent):void
  {
  }
  protected function setupCollision():void
  {
  collisionArea = graphics.bitmap.rect;
  }
  public function collision(other:GameObject):void
  {
  }
  }
  }
  Read more: http://www.brighthub.com/internet/web-development/ articles/11889.aspx?
  p=2#ixzz0Q3kP0KCc
  复制代码我们添加了两个属性:collisionArea和collisionName。collisionArea表示之前我们说过的矩
  形。collisionName定义了物体的类型。例如:武器拥有名字"PlayerWeapon",敌人拥有名字"Enemy"
  。默认名字为"None",用CollisionIdentifiers.NONE来指定。
  我们还添加了3个方法:collision, CollisionArea和setupCollision。collision方法是另一个空方
  法,需要子类去覆写。当碰撞检测到时,它将被GameObjectManager调用。setupCollision方法用于保存
  用于碰撞检测系统的图像大小。CollisionArea返回矩形包围盒当前的屏幕位置。(未完待续) 
  你或许会奇怪,既然包围盒与图像尺寸一样,为什么还要单独使用一个collisionArea属性呢?原因是在
  第7部分我们要将动画加入游戏。动画类将重写setupCollision方法。
  CollisionIdentifiers.aspackage
  {
  public class CollisionIdentifiers
  {
  public static const NONE:String = "None";
  public static const PLAYER:String = "Player";
  public static const PLAYERWEAPON:String = "PlayerWeapon";
  public static const ENEMYWEAPON:String = "EnemyWeapon";
  public static const ENEMY:String = "Enemy";
  public static const POWERUP:String = "Powerup";
  }
  }
  Read more: http://lp2.fanqiang.org/browse.php?
  u=Oi8vd3d3LmJyaWdodGh1Yi5jb20vaW50ZXJuZXQvd2ViLWRl dmVsb3BtZW50L2FydGljbGVzLzExODg5LmFzcHg%
  2FcD0y&b=5#ixzz0Q6NoySPG
  复制代码和ZOrders类一样,CollisionIdentifiers类用于保存一些预先设定的静态值。为了防止名字撞
  车。CollisionIdentifiers.PLAYER进行自我解释,就是说"Player"字符串并不代表其本身的意思。
  接下来看一下GameObjectManager类。
  GameObjectManager.aspackage
  {
  import flash.display.*;
  import flash.events.*;
  import flash.utils.*;
  import mx.collections.*;
  import mx.core.*;
  public class GameObjectManager
  {
  // double buffer
  public var backBuffer:BitmapData;
  // colour to use to clear backbuffer with
  public var clearColor:uint = 0xFF0043AB;
  // static instance
  protected static var instance:GameObjectManager = null;
  // the last frame time
  protected var lastFrame:Date;
  // a collection of the GameObjects
  protected var gameObjects:ArrayCollection = new ArrayCollection();
  // a collection where new GameObjects are placed, to avoid adding items
  // to gameObjects while in the gameObjects collection while it is in a loop
  protected var newGameObjects:ArrayCollection = new ArrayCollection();
  // a collection where removed GameObjects are placed, to avoid removing items
  // to gameObjects while in the gameObjects collection while it is in a loop
  protected var removedGameObjects:ArrayCollection = new ArrayCollection();
  protected var collisionMap:Dictionary = new Dictionary();
  static public function get Instance():GameObjectManager
  {
  if ( instance == null )
  instance = new GameObjectManager();
  return instance;
  }
  public function GameObjectManager()
  {
  if ( instance != null )
  throw new Error( "Only one Singleton instance should be instantiated" );
  backBuffer = new BitmapData(Application.application.width, Application.application.height, 
  false);
  }
  public function startup():void
  {
  lastFrame = new Date();
  }
  public function shutdown():void
  {
  shutdownAll();
  }
  public function enterFrame():void
  {
  // Calculate the time since the last frame
  var thisFrame:Date = new Date();
  var seconds:Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;
  lastFrame = thisFrame;
  removeDeletedGameObjects();
  insertNewGameObjects();
  Level.Instance.enterFrame(seconds);
  checkCollisions();
  // now allow objects to update themselves
  for each (var gameObject:GameObject in gameObjects)
  {
  if (gameObject.inuse)
  gameObject.enterFrame(seconds);
  }
  drawObjects();
  }
  public function click(event:MouseEvent):void
  {
  for each (var gameObject:GameObject in gameObjects)
  {
  if (gameObject.inuse) gameObject.click(event);
  }
  }
  public function mouseDown(event:MouseEvent):void
  {
  for each (var gameObject:GameObject in gameObjects)
  {
  if (gameObject.inuse) gameObject.mouseDown(event);
  }
  }
  public function mouseUp(event:MouseEvent):void
  {
  for each (var gameObject:GameObject in gameObjects)
  {
  if (gameObject.inuse) gameObject.mouseUp(event);
  }
  }
  public function mouseMove(event:MouseEvent):void
  {
  for each (var gameObject:GameObject in gameObjects)
  {
  if (gameObject.inuse) gameObject.mouseMove(event);
  }
  }
  protected function drawObjects():void
  {
  backBuffer.fillRect(backBuffer.rect, clearColor);
  // draw the objects
  for each (var gameObject:GameObject in gameObjects)
  {
  if (gameObject.inuse)
  gameObject.copyToBackBuffer(backBuffer);
  }
  }
  public function addGameObject(gameObject:GameObject):void
  {
  newGameObjects.addItem(gameObject);
  }
  public function removeGameObject(gameObject:GameObject):void
  {
  removedGameObjects.addItem(gameObject);
  }
  protected function shutdownAll():void
  {
  // don't dispose objects twice
  for each (var gameObject:GameObject in gameObjects)
  {
  var found:Boolean = false;
  for each (var removedObject:GameObject in removedGameObjects)
  {
  if (removedObject == gameObject)
  {
  found = true;
  break;
  }
  }
  if (!found)
  gameObject.shutdown();
  }
  }
  protected function insertNewGameObjects():void
  {
  for each (var gameObject:GameObject in newGameObjects)
  {
  for (var i:int = 0; i  gameObject.zOrder ||
  gameObjects.getItemAt(i).zOrder == -1)
  break;
  }
  gameObjects.addItemAt(gameObject, i);
  }
  newGameObjects.removeAll();
  }
  protected function removeDeletedGameObjects():void
  {
  // insert the object acording to it's z position
  for each (var removedObject:GameObject in removedGameObjects)
  {
  var i:int = 0;
  for (i = 0; i 
  width="600"
  height="400"
  frameRate="100"
  creationComplete="creationComplete()"
  enterFrame="enterFrame(event)"
  click="click(event)"
  mouseDown="mouseDown(event)"
  mouseUp="mouseUp(event)"
  mouseMove="mouseMove(event)"
  currentState="MainMenu">
  
  
  
  
  
  
  
  
  
  width="100%" height="100%" id="myCanvas"/>
  
  
  
  
  Read more: http://lp2.fanqiang.org/browse.php?
  u=Oi8vd3d3LmJyaWdodGh1Yi5jb20vaW50ZXJuZXQvd2ViLWRl dmVsb3BtZW50L2FydGljbGVzLzExODg5LmFzcHg%
  2FcD00&b=5#ixzz0Q6b4QzFf
  复制代码任意两个物体只需要调用一次addCollidingPair方法。玩家飞船将与敌人检测碰撞,敌人将和子
  弹进行碰撞,玩家飞船也将与敌人进行碰撞。
  接下来我们我们要更新Player, Weapon和Enemy类的collisionName和响应碰撞。接下来我们看Player类
  Player.aspackage
  {
  import flash.events.*;
  import flash.geom.*;
  import mx.core.*;
  public class Player extends GameObject
  {
  protected static const TimeBetweenShots:Number = 0.25;
  protected var shooting:Boolean = false;
  protected var timeToNextShot:Number = 0;
  public function Player()
  {
  }
  public function startupPlayer():void
  {
  startupGameObject(ResourceManager.BrownPlaneGraphi cs, new Point
  (Application.application.width / 2, Application.application.height / 2), 
  ZOrders.PlayerZOrder);
  shooting = false;
  timeToNextShot = 0;
  this.collisionName = CollisionIdentifiers.PLAYER;
  }
  override public function shutdown():void
  {
  super.shutdown();
  }
  override public function enterFrame(dt:Number):void
  {
  super.enterFrame(dt);
  timeToNextShot -= dt;
  if (timeToNextShot  Application.application.width - graphics.bitmap.width)
  position.x = Application.application.width - graphics.bitmap.width;
  if (position.y  Application.application.height - graphics.bitmap.height )
  position.y = Application.application.height - graphics.bitmap.height ;
  }
  override public function mouseDown(event:MouseEvent):void
  {
  shooting = true;
  }
  override public function mouseUp(event:MouseEvent):void
  {
  shooting = false;
  }
  override public function collision(other:GameObject):void
  {
  Level.Instance.levelEnd = true;
  this.shutdown();
  }
  }
  }
  Read more: http://lp2.fanqiang.org/browse.php?
  u=Oi8vd3d3LmJyaWdodGh1Yi5jb20vaW50ZXJuZXQvd2ViLWRl dmVsb3BtZW50L2FydGljbGVzLzExODg5LmFzcHg%
  2FcD01&b=5#ixzz0Q6eJzeNp
  复制代码有两处改变让其对碰撞检测系统进行适应。第一个是startup方法中设置了collisionName。第二
  个是加入collision方法,这个方法将被GameObjectManager在碰撞发生时调用。这里我们注意,Level在
  设置levelEnd为true后应当停止(玩家挂了),我们还要调用shutdown来去掉玩家。
  除了levelEnd的改变外,Enemy和Weapon类完全一致,这里我(作者,不是译者)偷懒就不再展示了。
  最后是Level类的改变,如下: 
  Level.aspackage
  {
  import flash.events.*;
  import flash.geom.*;
  import flash.media.*;
  import flash.net.*;
  import flash.utils.*;
  import mx.collections.ArrayCollection;
  import mx.core.*;
  public class Level
  {
  protected static var instance:Level = null;
  protected static const TimeBetweenLevelElements:Number = 2;
  protected static const TimeBetweenEnemies:Number = 3;
  protected static const TimeBetweenClouds:Number = 2.5;
  protected static const TimeToLevelEnd:Number = 2;
  protected var timeToNextLevelElement:Number = 0;
  protected var levelElementGraphics:ArrayCollection = new ArrayCollection();
  protected var timeToNextEnemy:Number = 0;
  protected var enemyElementGraphics:ArrayCollection = new ArrayCollection();
  protected var timeToNextCloud:Number = 0;
  protected var timeToLevelEnd:Number = 0;
  public var levelEnd:Boolean = false;
  static public function get Instance():Level
  {
  if ( instance == null )
  instance = new Level();
  return instance;
  }
  public function Level(caller:Function = null )
  {
  if ( Level.instance != null )
  throw new Error( "Only one Singleton instance should be instantiated" );
  levelElementGraphics. addItem(ResourceManager.SmallIslandGraphics);
  levelElementGraphics. addItem(ResourceManager.BigIslandGraphics);
  levelElementGraphics. addItem(ResourceManager.VolcanoIslandGraphics);
  enemyElementGraphics. addItem(ResourceManager.SmallBluePlaneGraphics);
  enemyElementGraphics. addItem(ResourceManager.SmallGreenPlaneGraphics);
  enemyElementGraphics. addItem(ResourceManager.SmallWhitePlaneGraphics);
  }
  public function startup():void
  {
  timeToNextLevelElement = 0;
  new Player().startupPlayer();
  timeToLevelEnd = TimeToLevelEnd;
  levelEnd = false;
  }
  public function shutdown():void
  {
  }
  public function enterFrame(dt:Number):void
  {
  // add a background element
  timeToNextLevelElement -= dt;
  if (timeToNextLevelElement <= 0)
  {
  timeToNextLevelElement = TimeBetweenLevelElements;
  var graphics:GraphicsResource = levelElementGraphics.getItemAt(MathUtils.randomInt eger(0, 
  levelElementGraphics.length)) as GraphicsResource;
  var backgroundLevelElement:BackgroundLevelElement = BackgroundLevelElement.pool.ItemFromPool 
  as BackgroundLevelElement;
  backgroundLevelElement.startupBackgroundLevelEleme nt(
  graphics,
  new Point(Math.random() * Application.application.width, -graphics.bitmap.height),
  ZOrders.BackgoundZOrder,
  50);
  }
  // add an emeny
  timeToNextEnemy -= dt;
  if (timeToNextEnemy <= 0)
  {
  timeToNextEnemy = TimeBetweenEnemies;
  var enemygraphics:GraphicsResource = enemyElementGraphics.getItemAt(MathUtils.randomInt eger
  (0, enemyElementGraphics.length)) as GraphicsResource;
  var enemy:Enemy = Enemy.pool.ItemFromPool as Enemy;
  enemy.startupBasicEnemy(
  enemygraphics,
  new Point(Math.random() * Application.application.width, -enemygraphics.bitmap.height),
  55);
  }
  // add cloud
  timeToNextCloud -= dt;
  if (timeToNextCloud <= dt)
  {
  timeToNextCloud = TimeBetweenClouds;
  var cloudBackgroundLevelElement:BackgroundLevelElement = 
  BackgroundLevelElement.pool.ItemFromPool as BackgroundLevelElement;
  cloudBackgroundLevelElement. startupBackgroundLevelElement(
  ResourceManager.CloudGraphics,
  new Point(Math.random() * Application.application.width, -
  ResourceManager.CloudGraphics.bitmap.height),
  ZOrders.CloudsBelowZOrder,
  75);
  }
  if (levelEnd)
  timeToLevelEnd -= dt;
  if (timeToLevelEnd <= 0)
  Application.application.currentState = "MainMenu";
  }
  }
  }
  Read more: http://lp2.fanqiang.org/browse.php?
  u=Oi8vd3d3LmJyaWdodGh1Yi5jb20vaW50ZXJuZXQvd2ViLWRl dmVsb3BtZW50L2FydGljbGVzLzExODg5LmFzcHg%
  2FcD02&b=5#ixzz0Q6g1pVM4
  复制代码主要改变就是当玩家挂掉时通过levelEnd通知Level。当被设置为true时,enterFrame中使用
  timeToLevelEnd属性,进行倒数,当timeToLevelEnd为0时,state回到MainMenu(菜单画面)。
  碰撞检测在任何一个动作游戏中都很重要。我们目前用得比较简单,不过很有效。不幸的是,现在击中敌
  机只会简单的消失,在第7部分中,我们将加入动画效果。
  结果: http://flexfighters.sourceforge.net/flexfighters6. html
分享到:
评论

相关推荐

    FLEX和Actionscript开发FLASH游戏.rar

    1. 游戏规则:文件“FLEX和Actionscript开发FLASH游戏3-2.doc”和“FLEX和Actionscript开发FLASH游戏3-4.doc”可能涉及如何编写游戏规则,如角色移动、碰撞检测、游戏胜利条件等。 2. AI设计:简单到复杂的AI算法...

    使用FLEX 和 Actionscript开发FLASH 游戏(一)

    【使用FLEX和ACTIONSCRIPT开发FLASH游戏】 在开发FLASH游戏时,FLEX和ACTIONSCRIPT是两个重要的技术。FLEX是一个开放源代码的框架,用于构建富互联网应用(RIA),而ACTIONSCRIPT是Adobe Flash环境中用于创建交互性...

    FLEX和Actionscript开发FLASH游戏

    **游戏开发**:使用FLEX和ActionScript开发游戏时,通常会遵循以下步骤: 1. **设计游戏概念**:确定游戏玩法、目标、角色和环境。 2. **UI开发**:使用FLEX构建游戏界面,如菜单、计分板、游戏区域等。 3. **编写...

    FLEX和Actionscript开发FLASH游戏 flash游戏开发文档

    在游戏开发中,ActionScript可以用于创建游戏对象(如角色、敌人、道具等),实现碰撞检测,管理游戏状态,以及处理用户输入。例如,你可以用ActionScript定义一个名为“Player”的类,包含位置、速度和动作方法,...

    使用FLEX 和 Actionscript开发FLASH 游戏(五)

    在这一部分中,我们将深入探讨如何使用FLEX和Actionscript开发FLASH游戏,特别是关于增加敌机和游戏者的武器。在前四部分的学习中,我们已经构建了基础的游戏框架,包括用户输入和滚动背景。现在,我们将利用已有的...

    使用FLEX 和 Actionscript开发FLASH 游戏(六)-4

    在本教程中,我们将深入探讨如何使用FLEX和ActionScript来开发Flash游戏,特别是关于碰撞检测这一关键功能。碰撞检测是游戏开发中的一个重要环节,它允许我们检测游戏对象之间是否发生接触,从而触发相应的游戏逻辑...

    使用FLEX 和 Actionscript开发FLASH 游戏(三)-2

    在本教程中,我们将深入探讨如何使用FLEX和ActionScript来开发Flash游戏,特别是关于嵌入资源和添加游戏元素的部分。FLEX是一个基于MXML和ActionScript的框架,用于构建富互联网应用程序(RIA),而ActionScript是...

    使用FLEX 和 Actionscript 开发FLASH 游戏6-2

    总结来说,使用FLEX和ActionScript开发Flash游戏,你需要理解游戏对象的结构和生命周期管理,以及如何实现基本的碰撞检测机制。通过编写和优化这些功能,可以创建出丰富、互动性强的Flash游戏。

    使用FLEX 和 Actionscript开发FLASH 游戏(六)-3

    在本篇关于使用FLEX和Actionscript开发FLASH游戏的文章中,我们将专注于游戏对象管理器(GameObjectManager)的实现,特别是碰撞检测这一关键功能。GameObjectManager是游戏引擎的核心组件,负责处理游戏对象的生命...

    使用FLEX 和 Actionscript开发FLASH 游戏(六)-1

    在使用FLEX和ActionScript开发FLASH游戏的过程中,碰撞检测是一个非常关键的部分,它涉及到游戏对象间的交互和游戏逻辑的正确执行。在这个部分,我们将详细讨论`GameObject`类,它是所有游戏对象的基础,以及如何...

    使用FLEX和 Actionscript 开发FLASH游戏(八)-2

    ### 使用FLEX和ActionScript开发FLASH游戏:音乐与声效管理 #### 一、引言 在本章节中,我们将深入探讨如何使用Flex和ActionScript技术来开发Flash游戏中的音乐和声效部分。通过分析提供的代码片段,我们将了解如何...

    使用FLEX 和 Actionscript 开发FLASH 游戏7-4

    在使用FLEX和Actionscript开发Flash游戏时,我们经常会遇到各种技术细节和设计模式。在这个场景中,`Enemy`类是一个关键的组件,它是基于`AnimatedGameObject`抽象类来创建的,用于实现敌人的动画和行为逻辑。以下是...

    使用FLEX 和 Actionscript开发FLASH 游戏(七)-1

    在本篇关于“使用FLEX和Actionscript开发FLASH游戏”的教程中,我们将关注如何通过位图动画为游戏增添更丰富的视觉效果,特别是在制作爆炸等动态效果时。在第六部分,我们已经实现了简单的碰撞检测,但敌机被击中后...

    使用FLEX 和 Actionscript 开发FLASH 游戏6-5

    在开发Flash游戏时,FLEX和Actionscript是两个关键的技术工具。FLEX是一种基于Adobe Flex框架的开放源代码SDK,用于构建富互联网应用程序(RIA),而Actionscript是用于控制Flash内容的编程语言。本教程将关注如何...

    使用FLEX 和 Actionscript 开发FLASH 游戏3-1

    在本教程中,我们将深入探讨如何使用Adobe Flex和ActionScript来开发Flash游戏。在这个阶段,我们将专注于嵌入图像资源和在游戏中添加元素。首先,我们看到`main.mxml`文件已经包含了一些基本的游戏框架,包括应用的...

    使用FLEX 和 Actionscript开发FLASH 游戏(七)-2

    在使用FLEX和Actionscript开发FLASH游戏的过程中,创建动态、引人入胜的动画效果是至关重要的。在本文中,我们将深入探讨如何利用`AnimatedGameObject`类实现位图动画。`AnimatedGameObject`类是对基本`GameObject`...

    使用FLEX 和 Actionscript开发FLASH 游戏(六)-6

    ### 使用FLEX 和 Actionscript 开发 FLASH 游戏——碰撞检测 #### 一、概述 在继续探索如何使用 FLEX 和 ActionScript 开发 FLASH 游戏的过程中,本篇重点介绍了碰撞检测这一关键技术,并通过具体代码示例展示了...

    使用FLEX 和 Actionscript开发FLASH 游戏(三)-3

    在开发Flash游戏的过程中,使用FLEX和Actionscript作为主要工具,可以实现丰富的交互性和动态效果。本篇将探讨如何利用这两个技术创建游戏元素,并重点解析`GameObject`类的设计及其重要属性。 `GameObject`类是...

    flex游戏开发demo

    Flex游戏开发Demo是一个展示如何使用Adobe Flex技术进行游戏制作的实例。Flex是一种基于ActionScript 3.0的开源框架,用于构建富互联网应用程序(RIA)。它允许开发者使用MXML和ActionScript来创建交互式、高性能的...

    使用Adobe Flex开发的Flash小游戏-黄金矿工.zip

    通过学习和实践使用Adobe Flex开发“黄金矿工”这样的Flash小游戏,开发者不仅能掌握Flex的基础知识,还能深入理解游戏开发的原理,提升在RIA领域的专业技能。在压缩包“Flex-GoldMiner-master”中,包含了游戏的源...

Global site tag (gtag.js) - Google Analytics