actor2d.java

来自「java learn PPT java learn PPT java learn」· Java 代码 · 共 358 行

JAVA
358
字号
package magic.actor2d;

import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import magic.graphics.*;

// 这个类封装了移动和绘制一个2-D游戏对象所需要的一般信息
public abstract class Actor2D
    extends Object
    implements Moveable
{
  // 一个actor具有的一般状态
  public final int STATE_ALIVE = 1;
  public final int STATE_DYING = 2;
  public final int STATE_DEAD = 4;

  // 这个actor的当前状态
  protected int state;

  // 所属的角色组
  protected ActorGroup2D group;

  // acotr位置,速度和旋转,以及缓存的变换
  protected Vector2D pos;
  protected Vector2D vel;
  protected double rotation;
  protected AffineTransform xform;

  protected final double TWO_PI = 2 * Math.PI;

  // 冲突检测用的边界矩形
  protected Rectangle2D bounds;

  // 和这个actor有冲突的acotr列表
  protected LinkedList collisionList;

  // 宽和高
  protected int frameWidth;
  protected int frameHeight;

  // 指向当前动画条的引用
  protected AnimationStrip currAnimation;

  // 播放下一帧之前需要等待的帧数,和一个帧计数器
  protected int animWait;
  protected int animCount;

  // 创建一个属于给定ActorGroup的Actor2D对象
  public Actor2D(ActorGroup2D grp)
  {
    group = grp;

    bounds = new Rectangle2D.Double();
    collisionList = new LinkedList();

    state = 0;

    pos = new Vector2D.Double();
    vel = new Vector2D.Double();
    rotation = 0;
    xform = new AffineTransform();

    currAnimation = null;
    animWait = 0;
    animCount = 0;

    frameWidth = 0;
    frameHeight = 0;
  }

  // 每隔animWait帧,移动一下actor
  public void animate()
  {
    if (currAnimation != null) {
      if (++animCount >= animWait) {
        currAnimation.getNextFrame();
        animCount = 0;
      }
    }
  }

  // 使用它自身的变换来绘制actor
  public void paint(Graphics2D g2d)
  {
    if (currAnimation != null) {
      g2d.drawImage(currAnimation.getCurrFrame(), xform,
                    AnimationStrip.observer);
    }
  }

  // 在x,y坐标处绘制 actor
  public void paint(Graphics2D g2d, double x, double y)
  {
    if (currAnimation != null) {
      g2d.drawImage(currAnimation.getCurrFrame(),
                    AffineTransform.getTranslateInstance(x, y),
                    AnimationStrip.observer
                    );
    }
  }

  // 简单边界盒子,判断actor是否和传入的actor冲突
  public boolean intersects(Actor2D other)
  {
    return bounds.intersects(other.getBounds());
  }

  // 根据当前的x和y位置更新边界盒子
  public void updateBounds()
  {
    // make sure we know the correct width and height of the actor
    if (frameWidth <= 0 && currAnimation != null) {
      frameWidth = currAnimation.getFrameWidth();
    }
    if (frameHeight <= 0 && currAnimation != null) {
      frameHeight = currAnimation.getFrameHeight();
    }

    bounds.setRect(pos.getX(), pos.getY(), frameWidth, frameHeight);
  }

  // 确保actor的边界没有超出actor组所限定的边界
  public void checkBounds()
  {
    if (group == null)
      return;

    if (bounds.getX() < group.MIN_X_POS) {
      pos.setX(group.MIN_X_POS);
    }

    else if (bounds.getX() + frameWidth > group.MAX_X_POS) {
      pos.setX(group.MAX_X_POS - frameWidth);
    }

    if (bounds.getY() < group.MIN_Y_POS) {
      pos.setY(group.MIN_Y_POS);
    }

    else if (bounds.getY() + frameHeight > group.MAX_Y_POS) {
      pos.setY(group.MAX_Y_POS - frameHeight);
    }
  }

  // 返回一个描述这个acotr的字符串
  public String toString()
  {
    return super.toString();
  }

  // 把传入的值和当前的属性值进行位或操作
  public final void setState(int attr)
  {
    state |= attr;
  }

  // 使用位与或者非重新设置属性
  public final void resetState(int attr)
  {
    state &= ~attr;
  }

  public final int getState()
  {
    return state;
  }

  public final void clearState()
  {
    state = 0;
  }

  // 判断所传入的状态属性是否被actor的状态属性所包含
  public final boolean hasState(int attr)
  {
    return ( (state & attr) != 0);
  }

  // actor的速度,位置和旋转访问方法

  public final void setX(double px)
  {
    pos.setX(px);
  }

  public final void setY(double py)
  {
    pos.setY(py);
  }

  public final double getX()
  {
    return pos.getX();
  }

  public final double getY()
  {
    return pos.getY();
  }

  public final void setPos(int x, int y)
  {
    pos.setX(x);
    pos.setY(y);
  }

  public final void setPos(double x, double y)
  {
    pos.setX(x);
    pos.setY(y);
  }

  public final void setPos(Vector2D v)
  {
    pos.setX(v.getX());
    pos.setY(v.getY());
  }

  public final Vector2D getPos()
  {
    return pos;
  }

  public final void setRot(double theta)
  {
    rotation = theta;
  }

  public final double getRot()
  {
    return rotation;
  }

  public final void rotate(double theta)
  {
    rotation += theta;

    while (rotation > TWO_PI) {
      rotation -= TWO_PI;
    }
    while (rotation < -TWO_PI) {
      rotation += TWO_PI;
    }
  }

  public final void setVel(int x, int y)
  {
    vel.setX(x);
    vel.setY(y);
  }

  public final void setVel(Vector2D v)
  {
    vel.setX(v.getX());
    vel.setY(v.getY());
  }

  public final Vector2D getVel()
  {
    return vel;
  }

  public final void moveBy(double x, double y)
  {
    pos.translate(x, y);
  }

  public final void moveBy(int x, int y)
  {
    pos.translate(x, y);
  }

  public final void moveBy(Vector2D v)
  {
    pos.translate(v);
  }

  public final void accelerate(double ax, double ay)
  {
    vel.setX(vel.getX() + ax);
    vel.setY(vel.getY() + ay);
  }

  public int getWidth()
  {
    return frameWidth;
  }

  public int getHeight()
  {
    return frameHeight;
  }

  // 从Moveable接口所继承的方法

  public Rectangle2D getBounds()
  {
    return bounds;
  }

  // 判断一个Moveable对象是否和这个对象冲突
  public boolean collidesWith(Moveable other)
  {
    if (this == other) {
      return false;
    }

    return (bounds.contains(other.getBounds()) ||
            other.getBounds().contains(bounds) ||
            bounds.intersects(other.getBounds()));
  }

  // 在冲突列表中添加一个冲突对象
  public void addCollision(Moveable other)
  {
    if (collisionList == null) {
      collisionList = new LinkedList();
      collisionList.add(other);
      return;
    }

    if (!collisionList.contains(other)) {
      collisionList.add(other);
    }
  }

  // 处理与冲突列表中对象之间冲突的stub 方法
  // this method is left empty, but not abstract
  public void processCollisions()
  {

  }

  // 更新对象的位置和边界盒子,移动它,然后更新变换
  public void update()
  {
    pos.translate(vel);

    updateBounds();
    checkBounds();

    animate();

    // 子类要覆盖这个方法的话,必须要求变换是以原点为中心的,
    // 而不是位置以原点为中心
    if (rotation != 0) {
      xform.setToIdentity();
      xform.translate(pos.getX() + frameWidth / 2, pos.getY() + frameHeight / 2);
      xform.rotate(rotation);
      xform.translate( -frameWidth / 2, -frameHeight / 2);
    }
    else {
      xform.setToTranslation(pos.getX(), pos.getY());
    }
  }

} // Actor2D

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?