Ball Objects

Dette eksempel viser hvordan kan benytte klasser og nedarvning i til at lave en simulering af hoppende bolde.

Der benyttes 3 klasser som illustreret i dette klasse diagram.

classDiagram Ball <|-- BouncingBall BouncingBall <|-- RandomBouncingBall Ball : constructor(position) Ball : update() Ball : render() Ball : r Ball : pos Ball : speed BouncingBall : update() RandomBouncingBall : lineWidth RandomBouncingBall : strokeColor RandomBouncingBall : fillColor RandomBouncingBall : constructor(position) RandomBouncingBall : render() RandomBouncingBall : _generateColors()

Det grundlæggende programflow håndteres i filen sketch.js.

let balls = []
let bouncingBalls = []
let randomBouncinBalls = []
let pos = new p5.Vector()

function setup() {
  createCanvas(windowWidth, windowHeight)
  pos.x = width / 2
  pos.y = height / 2
  reset()
  createBalls()
}

function draw() {
  background(220)
  renderBalls()
}

// === Helper functions
function reset(position) {
  balls = []
  bouncingBalls = []
  randomBouncinBalls = []
}

function createBalls() {
  for (let i = 0; i < 50; i++) {
    balls.push(new Ball(pos))
  }
}

function createBouncingBalls() {
  for (let i = 0; i < 20; i++) {
    bouncingBalls.push(new BouncingBall(pos))
  }
}

function createRandomBalls() {
  let spawnPoint = createVector(random(50, width - 50), random(50, height - 50))
  for (let i = 0; i < 20; i++) {
    randomBouncinBalls.push(new RandomBouncingBall(spawnPoint))
  }
}

function renderBalls() {
  for (const b of balls) {
    b.update()
    b.render()
  }
  for (const b of bouncingBalls) {
    b.update()
    b.render()
  }
  for (const b of randomBouncinBalls) {
    b.update()
    b.render()
  }
}

// === events ===
function mousePressed() {
  pos.x = mouseX
  pos.y = mouseY
  balls = []
  createBalls()

  if (keyIsDown(SHIFT)) {
    createBouncingBalls()
  }
}

function keyPressed() {
  if ('c' == key) {
    reset()
  }

  if ('r' == key) {
    createRandomBalls()
  } else if ('R' == key) {
    randomBouncinBalls = []
    createRandomBalls()
  }
}

Koden til klassen Ball ser sådan ud.

class Ball {
  constructor(position) {
    this.r = random(5, 40)
    this.pos = position.copy()

    this.speed = createVector()
    this.speed.x = random(-20,20)
    this.speed.y = random(-20,20)
  }

  update() {
    this.pos.add(this.speed)
  }

  render() {
    circle(this.pos.x, this.pos.y, this.r * 2)
  }
}

Koden til klassen BouncingBall ser sådan ud.

class BouncingBall extends Ball {
  update() {
    if (this.pos.x + this.r > width || this.pos.x - this.r < 0) {
      this.speed.x = -this.speed.x
    }
    if (this.pos.y + this.r > height || this.pos.y - this.r < 0) {
      this.speed.y = -this.speed.y
    }

    super.update()
  }
}

Her er koden til klassen RandomBouncingBall.

class RandomBouncingBall extends BouncingBall {
  constructor(pos) {
    super(pos);
    this.lineWidth = random(1,20)
    this._generateColors()
  }

  _generateColors() {
    this.strokeColor = color(random(255), random(255), random(255))
    this.fillColor = color(random(255), random(255), random(255))
  }

  render() {
    push()
    stroke(this.strokeColor)
    strokeWeight(this.lineWidth)
    fill(this.fillColor)
    super.render()
    pop()
  }
}

Demo

Prøv det kørende eksempel. Bemærk hvordan en del af boldene forsvinder ud af skærmen.

Materiale