HTX Frederikshavn & Hjørring

Det har aldrig været sjovere at være nørd

Brugerværktøjer

Webstedsværktøjer


prog:forloeb:boldkanon_p5

Boldkanon med ControlP5

ControlP5 er et bibliotek til Processing, som gør det nemt at lave grafiske brugerflader (GUI).

Med ControlP5 kan du hurtigt tilføje:

  • Knapper
  • Sliders (til at styre talværdier)
  • Toggles (on/off)
  • Rotor-knapper (drej for at ændre en værdi)
  • ..og meget mere.

ControlP5 kan gøre dine sketches interaktive, så din bruger nemt kan ændre ting(variable) i realtid.



Installation af ControlP5

  1. Åbn Processing.
  2. Gå til menuen: Sketch → Import Library → Add Library…
  3. I søgefeltet skriver du: ControlP5
  4. Vælg ControlP5 i listen og klik på Install
  5. Vent til installationen er færdig
  6. Nu kan du bruge import controlP5.*; i dine sketches

Projekt: Boldkanon

I dette projekt laver du et interaktivt program, hvor du kan skyde en bold mod et mål. Du styrer vinkel (med en rotor) og styrke (med en slider), og trykker på en knap for at skyde.
Bolden bevæger sig under tyngdekraften, så du skal regne lidt på vinkler og styrke.

Det minder om klassiske computerspil så som Scorched Earth eller Gorillas , hvor man også skal justere vinkel og styrke for at ramme sin modstander.

Formålet er at lære både programmering gennem „Use-Modify-Create“, du lærer at lave en interaktiv GUI og enkel fysik på en sjov måde.

  • Rotor-knap: Vinkel (0–90 grader)
  • Slider: Styrke (1–20)
  • Knap: Shoot
  • Bolden er en separat klasse med position, hastighed og bevægelse

Bold-klasse

class Ball {
  float x, y, vx, vy;
  boolean flying = false;
  float radius = 20;
 
  Ball() {
    x = 50;
    y = height - 50;
    vx = 0;
    vy = 0;
  }
 
  void shoot(float angle, float power) {
    float rad = radians(angle);
    vx = cos(rad) * power;
    vy = -sin(rad) * power;
    x = 50;
    y = height - 50;
    flying = true;
  }
 
  void update() {
    if (flying) {
      x += vx;
      y += vy;
      vy += 0.3; // tyngdekraft
    }
  }
 
  void display() {
    circle(x, y, radius);
  }
 
  boolean hitsTarget(float tx, float ty, float tw, float th) {
    if (x > tx && x < tx+tw && y > ty && y < ty+th) {
      flying = false;
      return true;
    }
    return false;
  }
}

Er der smartere måde at test om vi har ramt et mål?


Setup med ControlP5

import controlP5.*;
 
ControlP5 cp5;
float angle = 45; // rotor
float power = 10; // slider
Ball ball;
 
void setup() {
  size(600, 400);
  cp5 = new ControlP5(this);
 
  cp5.addKnob("angle")
     .setPosition(50, 330)
     .setRadius(40)
     .setRange(0, 90)
     .setValue(45);
 
  cp5.addSlider("power")
     .setPosition(180, 330)
     .setSize(200, 20)
     .setRange(1, 20)
     .setValue(10);
 
  cp5.addButton("shoot")
     .setPosition(430, 300)
     .setSize(80, 40);
 
  ball = new Ball();
  ball.y = 250;
}

Bemærk hvordan funktioner kaldes på output af funktioner. Det kaldes typisk “method chaining” (eller på dansk: kædning af metoder).


Shoot-funktion

void shoot() {
  ball.shoot(angle, power);
}

Events i ControlP5

Sådan fanger du events (hændelser) i ControlP5.

void controlEvent(ControlEvent ev) {
 
  if (ev.isController()) {
 
    // Gem navnet på controlleren i en variabel
    String navn = ev.getController().getName();
 
    // Vi tjekker hvilken knap eller 'control' der har afgivet en event.
    if (navn.equals("shoot")) {
      // vi henter værdierne 'angle' og 'power'
      float angleValue = cp5.getController("angle").getValue();
      float powerValue = cp5.getController("power").getValue();
 
      println("SKUD! - angle: " + angleValue + ", Power: " + powerValue);
      ball.shoot(angleValue, powerValue);
    }
  }
}

Forklaring:

  • controlEvent(ControlEvent ev) bliver automatisk kaldt, når en komponent sender et event.
  • ev.getController().getName() giver navnet på den komponent, der sendte eventet.
  • cp5.getController(„angle“).getValue(); henter værdi som controller 'angle' har.

Boldens bevægelse i draw()

void draw() {
  background(220);
 
  // mål
  rect(500, height-150, 40, 40);
 
  ball.update();
  ball.display();
 
  if (ball.hitsTarget(500, height-150, 40, 40)) {
    println("Ramt!");
  }
}

Øelser

  • Ændr tyngdekraften i `Ball.update()`
  • Flyt målet til en tilfældig position
  • Begræns antallet af skud
  • Vis vinkel med en pil

Fri opgave – Udvid projektet

  • Flere mål (lav evt en Target klasse til formålet)
  • Point-system
  • Reset-knap
  • Tilføj lyd. (Brug SoundFile library)
  • Vis boldens bane (trail)
  • Flere boldklasser med forskellige egenskaber (fx størrelse, hastighed)

prog/forloeb/boldkanon_p5.txt · Sidst ændret: af 127.0.0.1