Skip to content

GameObject Class

SoJS coder edited this page Dec 10, 2023 · 2 revisions

Attention Game Makers

Unless you know what you are doing, this page is probably not for you. You most likely want Polygon or Sprite

This page is for reference if you want to create your own GameObject

Parent class for Polygon and Sprite

How to extend:

  • draw(options): The draw method will be called on the object every frame. If it is not present, it will throw an error. To draw, use the provided canvas context (options.ctx) and camera angle (options.camera). The canvas that is being drawn on is also passed (options.canvas)

For full reference, here is the GameObject code, all formatted and commented out for your ease of use.

class GameObject {
  constructor(options) {
    // will physics work on this object?
    this.physicsEnabled = options.physicsEnabled;
    this.physicsOptions = options.physicsOptions;

    // unique ID for each object
    this.id = uid();

    // where can it move? set with scene.setBoundaries()
    this.bounds = [];
    this.boundsActive = false;

    // does nothing!
    this.pinned = true;
  }

  // changes an attribute of the object (non destructive). To return to the orignal object, use returnState.
  state(attr, value){
    this._state = {};
    Object.keys(this).forEach(key=>{
      if(key == "_state") return;
      this._state[key] = this[key]
    });
    this[attr] = value;
    console.log(this[attr])
  }

  // returns to the old state (before state() was called)
  returnState(){
    Object.keys(this._state).forEach(key=>{
      this[key] = this._state[key];
    })
  }

  // updates object physics 1 tick
  updatePhysics() {
    var vertices = this.body.vertices;
    if(this.square) {
      var width = (vertices[0].x-10) - (vertices[1].x+10);
      var height = (vertices[0].y-10) - (vertices[1].y+10);
      this.hitbox = [width,height];
      if(this.type == "sprite"){
        this.coordinates = [this.body.bounds.min.x,this.body.bounds.min.y];
        this.points = this.body.vertices.map(v=>{
          return [v.x,v.y]
        });
      }else if(this.type == "polygon"){
        this.points = this.body.vertices.map(v=>{
          return [v.x,v.y]
        });
        this.coordinates = findTopLeftMostPoint(this.points);
      }
    }else{
      this.points = this.body.vertices.map(v=>{
        return [v.x,v.y]
      });
      this.coordinates = findTopLeftMostPoint(this.points);
    }
  }

  // applies a force to the object (only works if physics enabled)
  applyForce(vector){
    var vec = Matter.Vector.create(vector[0],vector[1]);
    Matter.Body.applyForce(this.body,this.body.position,vec);
  }

  // modifies pin
  unpin() {
    this.pinned = false;
  }
  pin() {
    this.pinned = true
  }

  // up to you to fill
  draw({ ctx, camera, canvas}) { }

  // should return an array of points (eg: objects bounds). used for collision detection
  polify() { }

  // sets the object's bounds
  setBounds(bounds) {
    this.bounds = bounds;
    this.boundsActive = true;
  }
  disableBounds() {
    this.boundsActive = false;
  }
  activateBounds() {
    this.boundsActive = true;
  }

  // statically moves the object (no forces involved)
  moveStatic(vector){
    if(!this.physicsEnabled) return this.move(vector);
    var newX = this.body.position.x+vector[0];
    var newY = this.body.position.y + vector[1];
    Matter.Body.setPosition(this.body,Matter.Vector.create(newX,newY));
    return true;
  }

  // top level move function (works with both physics enabled and disabled)... needs helper functions getWidth(), getHeight() to be defined. Recommended to re-write based on your use case (if extending) 
  move(vector,continueAfterPhysics=true) {
    var newCoords = sumArrays(this.coordinates, vector);
    if(this.physicsEnabled){
      Matter.Body.setVelocity(this.body,{x:vector[0]+this.body.velocity.x,y:vector[1]+this.body.velocity.y});
      return true;
    }else{
      if(!continueAfterPhysics) return false;
    }
    if (this.boundsActive) {
      if (newCoords[0] < 0 || newCoords[0] + this.getWidth() > this.bounds[0] || newCoords[1] < 0 || newCoords[1] + this.getHeight() > this.bounds[1]) {
        var passesRightBound = (newCoords[0] + this.getWidth() > this.bounds[0]);
        var passesLeftBound = (newCoords[0] < 0);
        var passesTopBound = (newCoords[1] < 0);
        var passesBottomBound = (newCoords[1] + this.getHeight() > this.bounds[1]);
        if (passesRightBound) {
          this.coordinates[0] = this.bounds[0] - this.getWidth();
        }
        if (passesLeftBound) {
          this.coordinates[0] = 0;
        }
        if (passesTopBound) {
          this.coordinates[1] = 0;
        }
        if (passesBottomBound) {
          this.coordinates[1] = this.bounds[1] - this.getHeight();
        }
        return false;
      } else {
        this.coordinates = newCoords;
        return true;
      }
    } else {
      this.coordinates = newCoords;
      return true;
    }
  }

  // used polify() to check for a collision between this and that object (remember to set whether the bounds are square, or a convex polygon... changes the collision detection method used)
  checkCollision(object) {
    var p1 = this.polify();
    var p2 = object.polify();

    if ((this.square || this.convex) && (object.square || object.convex)) {
      return checkSquareCollision(p1, p2);
    } else {
      return checkCollision(p1, p2);
    }
  }
}
Clone this wiki locally