We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Currently trying to make a over complicated software to run alongside other software and I'm currrently trying to get something to register colour changes in pixels while holding down a key. However, after trying to figure out why my idea wasn't working after 2 hours of messing around, pressing keys aren't registered while tabbed out of the application window.
Is there a way around it?
import java.awt.Rectangle;
import java.awt.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.AWTException;
import java.awt.event.InputEvent;
import java.awt.event.KeyListener;
PImage screenshot;
int PixelY;
int PixelX;
int Trigger;
int buttons;
Robot robot;
int triggerkey;
static final String RENDERER = FX2D;
static final int FPS = 60, DELAY = 100/FPS/4, SMOOTH = 3;
void setup() {
size(1920, 1080, RENDERER);
smooth(SMOOTH);
frameRate(FPS);
imageMode(CORNER);
screenshot = createImage(displayWidth, displayHeight, ARGB);
thread("screenshotThread");
//
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
exit();
}
}
void draw() {
image(screenshot, 0, 0, width, height);
frame.setTitle("FPS : " + round(frameRate));
fill(1,1,1);
rect((1920/2),(1080/2+1),1,1);
PixelX = get((1920/2),(1080/2));
if(PixelY != PixelX){
print("Trigger Enabled");
Trigger = 1;
}
if (PixelY == PixelX){
Trigger = 0;
} else {
Trigger = 1;
println("Toggled");
}
delay(1);
PixelY = get((1920/2),(1080/2));
print("(");
print(PixelY);
print(":");
print(PixelX);
print("(");
println();
if (keyPressed) {
println(true);
if(key == 'f'){
println("Holding");
triggerkey = 1;
}
} else {
triggerkey = 0;
println(false);
}
}
void screenshotThread(){
final PImage shot = screenshot;
final Rectangle dimension = new Rectangle(displayWidth, displayHeight);
final Robot robot;
try {
robot = new Robot();
}
catch (AWTException cause) {
exit();
throw new RuntimeException(cause);
}
for (;; delay(DELAY)) grabScreenshot(shot, dimension, robot);
}
static final PImage grabScreenshot(PImage img, Rectangle dim, Robot bot) {
bot.createScreenCapture(dim).getRGB(
0, 0,
dim.width, dim.height,
img.pixels, 0, dim.width);
img.updatePixels();
return img;
}
void alt(KeyEvent e){
if(e.getKeyCode() == 18){
}
}
void keypressed(){
if(triggerkey == 1){
if(Trigger == 1){
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
print("Active");
println("");
delay(450);
}
}
}
Belatedly: because you also shared a class-based solution, here is simplified class-based solution which uses the global PMatrix -- it also works equally well in JAVA2D, FX2D, P2D, or P3D (although peasycam only works in P3D).
One limitation of this approach: it can only go to the depth of the global PMatrix. If you nest a large set of shapes in a long chain then you could run out of stack and the sketch will stop with an error. However for paper dolls, robot arms, or spiders et cetera this approach works great.
// RelativePShapeClass
// Jeremy Douglass 2018-05-14 Processing 3.3.6
// forum.processing.org/two/discussion/27880/how-to-rotate-a-pshape-relative-to-another
import peasy.PeasyCam;
PeasyCam cam;
LinkedShape[] shapes;
void setup() {
size(200, 200, P3D); // works with JAVA2D, FX2D, P2D, or P3D
cam = new PeasyCam(this, 300);
shapes = new LinkedShape[2];
LinkedShape ls0 = new LinkedShape(
createShape(RECT, 0, 0, 30, 30),
new PVector(0, 0, 0),
new PVector(0, 0, 0.5));
LinkedShape ls1 = new LinkedShape(
createShape(RECT, 0, 0, 30, 30),
new PVector(0, 0, 180),
new PVector(0, 0, 0.5));
LinkedShape c1 = new LinkedShape(
createShape(RECT, 0, 0, 20, 20),
new PVector(30, 30, 0),
new PVector(0, 0, 0.5));
LinkedShape c2 = new LinkedShape(
createShape(RECT, -6, -6, 12, 60),
new PVector(10, 10, 0),
new PVector(0, 0, 0.5));
LinkedShape c3 = new LinkedShape(
createShape(RECT, 0, 0, 30, 30),
new PVector(0, 60, 0),
new PVector(0, 0, 0.5));
shapes[0] = ls0;
shapes[1] = ls1;
ls0.children.add(c1);
ls1.children.add(c1);
c1.children.add(c2);
c2.children.add(c3);
}
void draw() {
background(150);
// translate(width/2, width/2);
pushMatrix();
for (int i=0; i< shapes.length; i++) {
shapes[i].display();
}
popMatrix();
}
class LinkedShape {
PShape ashape;
PVector offset;
PVector movement;
ArrayList<LinkedShape> children;
LinkedShape(PShape ashape, PVector offset, PVector movement) {
this.ashape = ashape;
this.offset = offset;
this.movement = movement;
children = new ArrayList<LinkedShape>();
}
void update() {
offset.add(this.movement);
}
void update(PVector m) {
offset.add(m);
}
void display() {
pushMatrix();
this.update();
translate(offset.x, offset.y);
rotate(radians(offset.z));
shape(ashape);
for (int i=0; i<children.size(); i++) {
children.get(i).display();
}
popMatrix();
}
}
Also, I forgot to include these lines at the very beginning, for the robot:
import java.awt.*;
import java.awt.event.*;
This thread has been closed, in favor of QueasyCam. You can now stop commenting.
P.S. I looked at the source code, and it uses camera(). I copied down the source code, and embedded it in my own script. Here it is, for a TerraTech clone instead of a Minecraft clone:
// Variables
String KEY_MOVE_FORWARD_1 = 'w';
String KEY_MOVE_FORWARD_2 = 'W';
String KEY_MOVE_LEFT_1 = 'a';
String KEY_MOVE_LEFT_2 = 'A';
String KEY_MOVE_BACK_1 = 's';
String KEY_MOVE_BACK_2 = 'S';
String KEY_MOVE_RIGHT_1 = 'd';
String KEY_MOVE_RIGHT_2 = 'D';
String KEY_MOVE_UP_1 = 'q';
String KEY_MOVE_UP_2 = 'Q';
String KEY_MOVE_DOWN_1 = 'e';
String KEY_MOVE_DOWN_1 = 'E';
String KEY_JUMP = ' ';
boolean debugMode = true;
float friction = 0.8;
int debugSetting = 0;
PVector mouse = new PVector();
PVector prevMouse = new PVector();
Robot robot = new Robot();
PVector forward = new PVector();
PVector right = new PVector();
PVector up = new PVector(0, 1, 0);
PVector position = new PVector();
PVector velocity = new PVector();
PVector center = new PVector();
void newGame() {
// Generate noise map
// Introduction sequence
// Tutorial sequence, if enabled in new game menu
}
void setup() {
// Title screen
// Menu (buttons, checkboxes, random seed, etc.)
}
void draw() {
// Mouse looping
if (mouse.x < 1 && (mouse.x - prevMouse.x) < 0) {
robot.mouseMove(width - 2, mouse.y);
mouse.x = width - 2;
prevMouse.x = width - 2;
}
if (mouse.x > width - 2 && (mouse.x - prevMouse.x) > 0) {
robot.mouseMove(2, mouse.y);
mouse.x = 2;
prevMouse.x = 2;
}
if (mouse.y < 1 && (mouse.y - prevMouse.y) < 0) {
robot.mouseMove(mouse.x, height - 2);
mouse.y = height - 2;
prevMouse.y = height - 2;
}
if (mouse.y > height - 1 && (mouse.y - prevMouse.y) > 0) {
robot.mouseMove(mouse.x, 2);
mouse.y = height - 2;
prevMouse.y = 2;
}
// Pan and tilt commands
pan += map(mouse.x - prevMouse.x, 0, width, 0, TAU) * sensitivity;
tilt += map(mouse.y - prevMouse.y, 0, height, 0, PI) * sensitivity;
tilt = constrain(tilt, -PI/2.01, PI/2.01);
if (tilt == PI/2) tilt += 0.001;
// Forward and right commands
forward.x = cos(pan);
forward.y = tan(tilt);
forward.z = sin(pan);
forward.normalize();
right.x = sin(pan);
right.y = 0;
right.z = -cos(pan);
// Controls
prevMouse.x = mouse.x;
prevMouse.y = mouse.y;
if (keyPressed) {
switch(key) {
case KEY_MOVE_FORWARD_1:
case KEY_MOVE_FORWARD_2:
velocity.add(PVector.mult(forward, speed));
break;
case KEY_MOVE_LEFT_1:
case KEY_MOVE_RIGHT_1:
velocity.add(PVector.mult(right, speed));
break;
case KEY_MOVE_BACK_1:
case KEY_MOVE_BACK_2:
velocity.sub(PVector.mult(forward, speed));
break;
case KEY_MOVE_RIGHT_1:
case KEY_MOVE_RIGHT_2:
velocity.sub(PVector.mult(right, speed));
break;
case KEY_JUMP:
velocity.add(PVector.mult(up, speed));
break;
}
if (debugMode) {
switch(key) {
case KEY_MOVE_UP_1:
case KEY_MOVE_UP_2:
velocity.add(PVector.mult(up, speed));
break;
case KEY_MOVE_DOWN_1:
case KEY_MOVE_DOWN_2:
velocity.sub(PVector.mult(up, speed));
break;
}
}
}
// Movement and camera
velocity.mult(friction);
position.add(velocity);
center = PVector.add(position, forward);
camera(position.x, position.y, position.z,
center.x, center.y, center.z,
up.x, up.y, up.z);
// Actual graphics
if (debugMode) {
switch(debugSetting) {
case 0:
// Wavy cubes
break;
case 1:
// Grid
break;
}
// Draw cube
} else {
// Draw tech(s)
// Draw terrain, generated in noise map
}
}
to be more specific as for the purpose of the application, i have an EV3 running LeJOS and i would like to send string messages to it with this app. this EV3 is part of a robot arm and the application will interface with another on the EV3.
I actually did! It took me a while but i made a simple camera class, easy to implement. In the end i just had to use the Robot class method mouseMove and play with the pmouseX and pmouseY variables. I'm kinda proud of it hahaha
If you want to give it a try, here is the code. If you want to test it on any P3D sketch, you have to set the main tab like this:
Camera camera;
void setup() {
size(width, height, P3D);
camera = new Camera(startingX, startingY, startingZ);
camera.setVelocity(0.5); //If not called, is set to 0.2 as default
}
void draw() {
background(someColor);
//RENDER SOMETHING HERE
camera.update();
}
void keyPressed() {
camera.keyPressed();
}
void keyReleased() {
camera.keyReleased();
}
Here is the Camera class. You move with WASD, SPACEBAR and SHIFT. Mouse movement is not really smooth, but works fine. There you go:
import java.awt.Robot;
class Camera{
public PVector pos;
private Robot robot;
private PVector vel, acc, normLR, normFB, facing;
private float horizontalAngle, verticalAngle;
private float centerX, centerY, centerZ;
private boolean left, right, forward, backwards, up, down;
private float velocity = 0.2;
private float fluidity = 0.9;
Camera(int x, int y, int z){
this.pos = new PVector(); //Camera position
this.vel = new PVector(); //Camera velocity
this.acc = new PVector(); //Camera acceleration
this.facing = new PVector(); //Facing direction
this.normLR = new PVector(); //Local x axis (Left and Right movement)
this.normFB = new PVector(); //Local y axis (Forward and Backwards movement)
this.pos.x = x; //Starting position given by arguments
this.pos.y = y;
this.pos.z = z;
try{
this.robot = new Robot();
}catch(Exception e){}
perspective(PI/3.0, (float) width/height, 0.001, 10000);
noCursor();
}
public void update(){
//CAMERA MOTION IN 3D SPACE
if(left)
this.acc.sub(normLR);
if(right)
this.acc.add(normLR);
if(forward)
this.acc.sub(normFB);
if(backwards)
this.acc.add(normFB);
if(down)
this.acc.z -= 1;
if(up)
this.acc.z += 1;
if(up == false && down == false && left == false && right == false && forward == false && backwards == false){
this.acc.mult(fluidity * 0.1);
this.vel.mult(fluidity);
}
this.acc.limit(velocity * 0.1);
this.vel.add(acc);
this.vel.limit(velocity);
this.pos.add(this.vel);
//CAMERA FACING
this.robot.mouseMove((int)getWindowLocation().x + width/2, (int)getWindowLocation().y + height/2);
pmouseX = width/2;
pmouseY = height/2;
this.horizontalAngle += (mouseX - pmouseX) * 0.01;
this.verticalAngle += (mouseY - pmouseY) * 0.01;
if(this.verticalAngle < -PI + 0.1)
this.verticalAngle = -PI + 0.1;
if(this.verticalAngle > -0.1)
this.verticalAngle = -0.1;
this.centerX = this.pos.x + cos(horizontalAngle) * sin(verticalAngle);
this.centerY = this.pos.y + sin(horizontalAngle) * sin(verticalAngle);
this.centerZ = this.pos.z - cos(verticalAngle);
this.facing.set(this.centerX - this.pos.x, this.centerY - this.pos.y, this.centerZ - this.pos.z);
this.facing.normalize();
//CALCULATE LOCAL X & Y AXES
this.normLR.set(1, -this.facing.x/(this.facing.y + 0.0001), 0);
if(this.facing.y > 0)
this.normLR.mult(-1);
this.normLR.normalize();
this.normFB.set(1, -this.normLR.x/(this.normLR.y + 0.0001), 0);
if(this.normLR.y > 0)
this.normFB.mult(-1);
this.normFB.normalize();
camera(this.pos.x, this.pos.y, this.pos.z, this.centerX, this.centerY, this.centerZ, 0, 0, -1);
}
public void setVelocity(float newVelocity) {
this.velocity = newVelocity;
}
public void setFluidity(float newFluidity) {
if(newFluidity < 0 || newFluidity > 1) {
newFluidity = 0.9;
println("Fluidity requires a value between 0 and 1! New fluidity was set to 0.9 (default).");
}
this.fluidity = newFluidity;
}
private PVector getWindowLocation() {
PVector l = new PVector();
com.jogamp.nativewindow.util.Point p = new com.jogamp.nativewindow.util.Point();
((com.jogamp.newt.opengl.GLWindow)surface.getNative()).getLocationOnScreen(p);
l.x = p.getX();
l.y = p.getY();
return l;
}
void keyPressed(){
if(key == CODED){
if(keyCode == SHIFT){
down = true;
}
}
if(key == ' '){
up = true;
}
if(key == 'w' || key == 'W'){
forward = true;
}
if(key == 'a' || key == 'A'){
left = true;
}
if(key == 's' || key == 'S'){
backwards = true;
}
if(key == 'd' || key == 'D'){
right = true;
}
}
void keyReleased(){
if(key == CODED){
if(keyCode == SHIFT){
down = false;
}
}
if(key == ' '){
up = false;
}
if(key == 'w' || key == 'W'){
forward = false;
}
if(key == 'a' || key == 'A'){
left = false;
}
if(key == 's' || key == 'S'){
backwards = false;
}
if(key == 'd' || key == 'D'){
right = false;
}
}
}
Hi everyone!
My name is Jun Shern, I'm a 4th (final) year student studying Electrical and Electronic Engineering at Imperial College London, and I'd love to come on board with the Processing community for Google Summer of Code 2018!
I'm hoping to work on the project "Algorithmic Composition with p5.Sound" on the project-lists page. I've been a huge fan of p5.js for years, and it so happens the topic of my (in-progress) Master's project this year is "Human-Robot Collaboration for Musical Tasks", which focuses on algorithmic composition applied to the task of live music accompaniment by a robot (Find out more about my background on my website, and resume). It would be a huge joy and honour to get the chance to apply my knowledge to creating new p5.js-sound examples and features!
The main idea is that I intend to build up features and support materials to enable users to get involved with algorithmic composition on p5.js. This will involve some new features (see my issue about MIDI), new examples and documentation. For more details please have a look at my proposal document, and feel free to leave comments on the document or in this forum!
I have already approached Jason Sigal via email as my potential mentor, and have started some discussions about the project on the issues pages on GitHub here and here.
I'm in the process of outlining the main components of my proposal here: https://docs.google.com/document/d/1uWFplDpLht1E8JM7l-M7XvzfZjx5BCA5FpMWsLxAq2o/edit?usp=sharing, and would love to get some early feedback from any interested parties.
Nice to meet you all!
float x = 100; float y; float breedte = 200; float hoogte = 300; float xOpnieuw, yOpnieuw; float xStop, yStop; final int MARGE_SCHERM_BREEDTE = 50; final int MARGE_SCHERM_HOOGTE = 80; final float ROBOTS_AANTAL = 500 / x; final String TERUG = "TERUG"; final String OPNIEUW = "OPNIEUW"; final String STOPPEN = "STOPPEN"; final String VOLGENDE = "VOLGENDE";
int sliderPositieRobots = 4; int sliderPositieMargeGrootte = 2;
//De geefKleur methode in de setup zorgt ervoor dat de robots //maar 1 keer een kleur krijgen en niet afwisselend een kleur. void setup () { size(700, 600); geefKleur(); }
void draw() { tekenScherm(); }
void mouseClicked() { schermClick(); }
void tekenStartScherm() { final String START = "START";
tekenWindow(LICHT_GRIJS); tekenLogo(); sliderPositieRobots = sliderPositieBepalen(x, y, int(ROBOTS_AANTAL), sliderPositieRobots, x+100, y+150); tekenSlider1(x, y, x + 100, y + 100, sliderPositieRobots, ROBOTS_AANTAL); tekenSlider2(x, y, x + 100, y + 100); tekenStartKnop(START); }
void startSchermClick() { if (isMuisInKnop(x, y, breedte, hoogte)) { volgendeScherm(SPEL_SCHERM); } }
color[] kleur = new int[int(sliderPositieRobots)];
void tekenSpelScherm() { tekenWindow(BRUIN); tekenBaan(); tekenRobots(); tekenTerugKnop(TERUG); tekenStopKnop(VOLGENDE); }
void spelSchermClick() { if (isMuisInKnop(xOpnieuw, yOpnieuw, breedte, hoogte)) { volgendeScherm(START_SCHERM); } else if (isMuisInKnop(xStop, yStop, breedte, hoogte)) { volgendeScherm(EIND_SCHERM); } }
//Het tekenen van de baan met de baanlijnen erop. //Ik heb de programma zo gemaakt dat er maximaal 4 robots kunnen racen dus 4 banen. void tekenBaan() { float aantalLijnen = ROBOTS_AANTAL + 1; int xBaan = MARGE_SCHERM_BREEDTE; int yBaan = MARGE_SCHERM_HOOGTE; int breedteBaanLijn = MARGE_SCHERM_BREEDTE; int hoogteBaanLijn = height - MARGE_SCHERM_HOOGTE;
int startFinishLijn = 2; int xStartFinish = MARGE_SCHERM_BREEDTE; int yStartFinish = MARGE_SCHERM_HOOGTE * 2; int breedteStartFinish = width - MARGE_SCHERM_BREEDTE; int hoogteStartFinish = MARGE_SCHERM_HOOGTE * 2;
//Baan lijnen voor de sprinters. for (int i = 0; i < aantalLijnen; i++) { line(xBaan, yBaan, breedteBaanLijn, hoogteBaanLijn); xBaan = xBaan + 150; breedteBaanLijn = breedteBaanLijn + 150; } //Start en Finish lijnen. for (int i = 0; i < startFinishLijn; i++) { line(xStartFinish, yStartFinish, breedteStartFinish, hoogteStartFinish); yStartFinish = yStartFinish + 275; hoogteStartFinish = hoogteStartFinish + 275; } }
//Het tekenen van de robots en het laten racen ervan. void tekenRobots() { frameRate(8); int robotNummer = 1; float x = 80; float stapGrootte = MARGE_SCHERM_BREEDTE * 3; y = height - MARGE_SCHERM_HOOGTE; y -= aantalGegooideOgen(); breedte = x; hoogte = breedte;
for (int i = 0; i < sliderPositieRobots; i++) { fill(kleur[i]); triangle(x, y, x + breedte / 2, y - hoogte, x + breedte, y);
fill(WIT);
textAlign(CENTER, CENTER);
text(robotNummer + i, x + 40, y - 40);
x = x + stapGrootte;
} }
//Een dobbelsteen wordt gegooid //en de robots kunnen met de gegooide aantal ogen bewegen in pixels. int aantalGegooideOgen() { int dobbelstenen = 6; int[] totaal = new int[dobbelstenen]; int optelling = 0; for (int i = 0; i < dobbelstenen; i++) { int aantalOgen = floor(random(6)); totaal[i] = aantalOgen; optelling = optelling+ totaal[i]; } return optelling; }
final String START_SCHERM = "start"; final String SPEL_SCHERM = "spel"; final String EIND_SCHERM = "eind";
String huidigeScherm = START_SCHERM;
void volgendeScherm(String scherm) { huidigeScherm = scherm; }
void tekenScherm() { background(GRIJS); switch(huidigeScherm) { case START_SCHERM: tekenStartScherm(); break; case SPEL_SCHERM: tekenSpelScherm(); break; case EIND_SCHERM: tekenEindScherm(); break; } }
void schermClick() { switch(huidigeScherm) { case START_SCHERM: startSchermClick(); break; case SPEL_SCHERM: spelSchermClick(); break; case EIND_SCHERM: eindSchermClick(); break; } }
final color WIT = #FFFFFF; final color ZWART = #000000; final color LICHT_GRIJS = #BBBBBB; final color GRIJS = #EEEEEE; final color BRUIN = #E86507; final int xTekst = 700 / 4; final int yTekstSlider1 = 600 / 3; final int yTekstSlider2 = 600 / 3;
Boolean isMuisInKnop(float x, float y, float breedte, float hoogte) { //Controleert door de gegeven variabelen of de muis "op" de knop staat. if (mouseX >= x && mouseX <= x + breedte && mouseY >= y && mouseY <= y + hoogte) { return true; } else { return false; } }
color donkerder(color kleur) { final float DONKERDER = 0.9; float r = constrain(red(kleur) * DONKERDER, 0, 255); float g = constrain(green(kleur) * DONKERDER, 0, 255); float b = constrain(blue(kleur) * DONKERDER, 0, 255);
return color(r, g, b); }
void tekenWindow(color kleur) { x = MARGE_SCHERM_BREEDTE; y = MARGE_SCHERM_HOOGTE; breedte = width - (MARGE_SCHERM_BREEDTE * 2); hoogte = height - (MARGE_SCHERM_HOOGTE * 2);
fill(kleur); rect(x, y, breedte, hoogte); }
//Tekent het logo met een kader eromheen. void tekenLogo() { x = width / 4; y = height / 6; int breedte = width / 2; int hoogte = height / 4; rect(x, y, breedte, hoogte);
PImage logo = loadImage("logo.png"); logo.resize(breedte - 1, hoogte - 1); image(logo, x + 1, y + 1); }
//Het tekenen van de slider voor het aantal robots met de tekst ervoor. //Ik heb het zo gedaan dat er maximaal 4 robots getekend kunnen worden door de slider. void tekenSlider1(float x, float y, float breedte, float hoogte, int positie, float nPosities) { float blokjeBreedte = breedte/nPosities; float xPosBlokje = x + 60 + positie * blokjeBreedte; x = width / 3; y = height / 2; breedte = x * 1.18; hoogte = 20;
fill(WIT); rect(x, y, breedte, hoogte); fill(#2257F0); rect(xPosBlokje - 2, y, blokjeBreedte, hoogte); fill(ZWART); textAlign(CENTER); text("Aantal Robots: " + positie , x - 50, y + 15); }
//Het tekenen van de slider voor de marge met de tekst ervoor. //Het is me niet gelukt om de slider tot werking te stellen icm de eerste slider. void tekenSlider2(float x, float y, float breedte, float hoogte) { x = width / 3; y = height * .6;
fill(WIT); rect(x, y, breedte, hoogte / 9);
fill(ZWART); textAlign(CENTER); text("Marge: ", x - 25, y + 15); }
//Het tekenen van de startknop op het startscherm. void tekenStartKnop(String titel) { final int BEWEGING_KNOP = 1;
x = width / 3; y = height / 1.5; breedte = width / 3; hoogte = height / 8;
color kleur = WIT;
if (isMuisInKnop(x, y, breedte, hoogte)) { kleur = donkerder(kleur); if (mousePressed) { x = x + BEWEGING_KNOP; y = y + BEWEGING_KNOP; } }
fill(kleur); rect(x, y, breedte, hoogte, hoogte / 4);
fill(ZWART); textAlign(CENTER, CENTER); text(titel, x + breedte / 2, y + hoogte / 2); }
//Het tekenen van de opnieuw knop om terug te keren naar het startscherm. void tekenTerugKnop(String titel) { final int BEWEGING_KNOP = 1;
xOpnieuw = width * .29; yOpnieuw = height * .87; breedte = width / 8; hoogte = height / 8;
color kleur = WIT;
if (isMuisInKnop(xOpnieuw, yOpnieuw, breedte, hoogte)) { kleur = donkerder(kleur); if (mousePressed) { x = x + BEWEGING_KNOP; y = y + BEWEGING_KNOP; } }
fill(kleur); rect(xOpnieuw, yOpnieuw, breedte, hoogte, hoogte / 4);
fill(ZWART); textAlign(CENTER, CENTER); text(titel, xOpnieuw + breedte / 2, yOpnieuw + hoogte / 2); }
//Het tekenen van de stop knop op het eindscherm om het programma af te sluiten. void tekenStopKnop(String titel) { final int BEWEGING_KNOP = 1;
xStop = width * .59; yStop = height * .87; breedte = width / 8; hoogte = height / 8;
color kleur = WIT;
if (isMuisInKnop(xStop, yStop, breedte, hoogte)) { kleur = donkerder(kleur); if (mousePressed) { x = x + BEWEGING_KNOP; y = y + BEWEGING_KNOP; } }
fill(kleur); rect(xStop, yStop, breedte, hoogte, hoogte / 4); fill(ZWART); textAlign(CENTER, CENTER); text(titel, xStop + breedte / 2, yStop + hoogte / 2); }
//Het aanmaken van willekeurige kleuren zodat elke robot een andere kleur krijgt. void geefKleur() { for (int i = 0; i < sliderPositieRobots; ++i) { kleur[i] = color(random(255), random(255), random(255)); } }
int bepaalPositie(float x, float breedte, int nPosities) { float blokjesBreedte = breedte / nPosities;
if (mouseX < x) { return 0; } else if (mouseX >= breedte + x) { return nPosities -1; } else { return floor((mouseX - x) / blokjesBreedte); } }
int sliderPositieBepalen(float beginPositieSliderTekstBreedte, float beginPositieSliderHoogte, int sliderNPosities, int sliderPositie, float sliderBreedte, float sliderHoogte) { if (mousePressed) { if (mouseX>=beginPositieSliderTekstBreedte &&mouseX<beginPositieSliderTekstBreedte+sliderBreedte &&mouseY>=beginPositieSliderHoogte&&mouseY <=beginPositieSliderHoogte+sliderHoogte) { sliderPositie=bepaalPositie(beginPositieSliderTekstBreedte, sliderBreedte, sliderNPosities); } } return sliderPositie; }
void tekenEindScherm() { tekenWindow(LICHT_GRIJS); tekenStopKnop(STOPPEN); tekenTerugKnop(OPNIEUW); tekenUitslagWindow(GRIJS); toonUitslag(x, y); }
void eindSchermClick() { if (isMuisInKnop(xStop, yStop, breedte, hoogte)) { exit(); } else if (isMuisInKnop(xOpnieuw, yOpnieuw, breedte, hoogte)) { volgendeScherm(START_SCHERM); } }
//Doordat het niet is gelukt om de robots te laten bewegen, is het helaas ook niet gelukt //om de winnaar te laten zien op het eindscherm, dus maar zo geimplementeerd. void toonUitslag(float x, float y) { int afstand = 15; x = width * .5; y = (MARGE_SCHERM_HOOGTE * 2) + afstand;
for (int i = 1; i <= sliderPositieRobots; i++) { fill(ZWART); text("Robot " + i, x, y); y = y + afstand; } }
void tekenUitslagWindow(color kleur) { x = MARGE_SCHERM_BREEDTE * 2; y = MARGE_SCHERM_HOOGTE * 2; breedte = width - (MARGE_SCHERM_BREEDTE * 4); hoogte = height - (MARGE_SCHERM_HOOGTE * 4);
fill(kleur); rect(x, y, breedte, hoogte); }
this is the code
There seems to be a 'rectangle' method in robot class, I'll look into whether thta can be set to grab a screenshot 1 x 370 pixels, then maybe put that into a Pimage and do the code on that? Is that what you mean?
On a slightly different note, the etiquette for 'Did this answer your question? Yes/No' is very unclear, as are th econsequences of either choice. I don't want to offend by marking 'no', but I dont want this thread to effectively close because its marked as 'answered.' It's very unfamiliar; plus this forum repeatedly crashes firefox.
This code is supposed to watch a window in another application to track the movement of a changing musical pitch represented by a blue horizontal line that always appears between (280, 230) and (280, 600) when a note is present but its unbelievably slow.
It searches for first pixel with the red value of '71' in a 370 pixel tall, 1 pixel wide column on my desktop, and returns it's y position. Finding this colour at, say (232,280) seems relatively quick, but finding it at (589,280) takes ten whole seconds from pressing the 'play' button, and around 6 seconds if the position of the blue line changes from y = 232 to y = 589.
import java.awt.Robot;
import java.awt.AWTException;
Robot robot;
void setup() {
try {
robot = new Robot();
}
catch (AWTException cause) {
exit();
throw new RuntimeException(cause);
}
}
//
void draw() {
for (int i = 230; i < 601; i++)
{
int p = robot.getPixelColor(280 , i).getRed();
if (p == 71) { // 71, 182, 240 is rgb to look for
println(i);
break;
}
}
}
My PC is plenty fast enough, it has a fairly decent graphics card even, but I'm shocked how slowly this runs. I had hoped it would look at all the pixels in maybe 1/50 of a second; I could probably sit there with a ruler and count the pixels off on that faster.
Is there any way to get this considerably faster?
Thanks
Hi guys, i'm trying to implement a first person camera for a little program i'm writing. I actually did implement the camera (it works with differentials and spherical coordinates) and it's doing quite well except for a problem. As i look around the scene (move my mouse), the cursor will eventually fall off the screen and of course stop working. How can i fix that? Here is my code:
void updateCamera(){
this.horizontalAngle += (mouseX - pmouseX)/100f;
this.verticalAngle -= (mouseY - pmouseY)/100f;
if(this.verticalAngle < -PI+0.1)
this.verticalAngle = -PI+0.1;
if(this.verticalAngle > 0)
this.verticalAngle = 0;
centerX = this.pos.x + cos(horizontalAngle) * sin(verticalAngle);
centerY = this.pos.y + sin(horizontalAngle) * sin(verticalAngle);
centerZ = this.pos.z + cos(verticalAngle);
camera(this.pos.x, this.pos.y, this.pos.z, this.centerX, this.centerY, this.centerZ, 0, 0, -1);
}
I tried the robot class with robot.mouseMove();
to set the mouse to center every time i move it, but in this way my camera gets locked. Suggestions? Thank you!
Realize that you only want to increase the counter when a robot SWITCHES from being off to on. If a robot is ALREADY on and you click again, well, you don't want to increase the counter AGAIN for that robot. This check - making sure a robot is OFF (not activated), then incrementing the counter, then turning it on - makes sure that each robot can only add to the counter once when it switches on.
There are some other things you could do now.
You could make Chansey into a class. This would simplify the logic inside draw() even more. This might be a good idea if the logic behind how Chansey works is going to get more complicated, for example, because you want to display more than one message. For example:
if( counter == 1 ) {
text("Even one is too many!", ... );
} else if( counter == 2) {
text("Stop turning the robots on!", ... );
} else if( counter == 3) {
text("Stop it NOW!", ... );
} else if( counter == 4) {
text("OH NO!", ... );
}
You might also look into using translate()
, push()
, and pop()
. This will help simplify the drawing of your robots (as you won't constantly need to be adding this.x and this.y to all your positions).
This lines
if ( !this.activated ) { // If the robot was off, but is now turning on..
counter++; // Add one to the counter.
}
are a little consusing tought.
I realised the background thing just a few minits before you answered it, and I laughted so much, because of the silly careless !!
I love the way you think it !! Thanks so much for the not depending robotClass-chansey-message.
The new if statement that supervises the color is a great idea, now I dont need a behavior for that. I could use this.activated in the if statement to make the chansey message, and make a different message for each robot. And then make a behavior in robotClass dependent of the counter, and make something if the counter is 4. Can I ?
Here's some nice changes that resolve a few issues:
var chansey;
let robots = [];
let counter = 0;
var https = "https://";
function preload() {
chansey = loadImage( https + "image.ibb.co/kZzhax/pzbykg5va9uz.png");
}
function setup() {
createCanvas(700, 600);
background(20);
for (var i = 0; i < 2; i++) {
for (var j = 0; j < 2; j++) {
robots.push(new Robot(i * 500 + 50, j * 400 + 75, 50));
}
}
}
function draw() {
background(20);
//drawing robot army.
for (let robot of robots) {
robot.drawRobot();
}
// chansey MESSAGE
if ( counter > 0 ) {
fill(255);
textSize(20);
text("STOP IT", 303, 370);
}
// counter
fill(0, 255, 0);
text( counter, 300, 400);
// Chansey image
image(chansey, 290, 250, 100, 100);
//button "make chansey happy" AKA reset
stroke(255);
fill(0);
rect(310, 0, 60, 30);
fill(255);
textSize(15);
text("Reset", 320, 20);
}
function mousePressed() {
for (let antennas of robots) {
antennas.turnOn(mouseX, mouseY);
}
//this make Chansey happy
// clicking the reset button
if (mouseX < 375 && mouseX > 315 && mouseY < 30 && mouseY > 0) {
for (let robot of robots) {
robot.activated = false;
}
counter = 0;
}
}
class Robot {
constructor(x, y, t) {
this.x = x;
this.y = y;
this.t = t;
this.swicherX = this.x + 25 / 50 * this.t;
this.swicherY = this.y - 15 / 50 * this.t;
this.swicherRadius = (15 / 50 * this.t) / 2;
//swicher color
this.b = 0;
//roboteyes color
this.red = 0;
this.green = 100;
this.blue = 300;
this.activated = false;
}
drawRobot() {
// Set colors based on activated state.
if(this.activated){
this.b = 255;
this.red = 255;
this.green = 50;
this.blue = 0;
} else {
this.b = 0;
this.red = 0;
this.green = 100;
this.blue = 300;
}
//stick of the antenna
stroke(0, 100, 300);
line(this.x + 2.5 / 5 * this.t, this.y + this.t / 10, this.x + 2.5 / 5 * this.t, this.y - 3 / 5 * this.t);
//swicher ball turnOn
stroke(100);
fill(255, 100, this.b);
ellipse(this.x + 25 / 50 * this.t, this.y - 15 / 50 * this.t, 15 / 50 * this.t, 15 / 50 * this.t);
//robot head
stroke(0);
fill(0, 0, 150);
rect(this.x - this.t / 10, this.y + this.t / 5, 60 / 50 * this.t, this.t / 5);
fill(100);
rect(this.x, this.y, this.t, 4.5 / 5 * this.t);
//eyes
fill(this.red, this.green, this.blue);
rect(this.x + 9 / 50 * this.t, this.y + this.t / 5, this.t / 5, this.t / 10);
rect(this.x + 3.2 / 5 * this.t, this.y + 1 / 5 * this.t, this.t / 5, this.t / 10);
//mouth
line(this.x + 1 / 5 * this.t, this.y + 3 / 5 * this.t, this.x + 4 / 5 * this.t, this.y + 3 / 5 * this.t);
}
turnOn(suicidetryX, suicidetryY) {
let proxToAntenna = dist(suicidetryX, suicidetryY, this.swicherX, this.swicherY);
if (proxToAntenna < this.swicherRadius) {
if ( !this.activated ) { // If the robot was off, but is now turning on..
counter++; // Add one to the counter.
}
this.activated = true;
}
}
}
Notice that each robot now has an "activated" variable that tracks if it has been clicked on. The drawRobot() function now uses that variable to determine the robot's colors. This also simplified a lot of the logic for resetting the robots, and the reset button now resets the counter too.
And now to address problem #1: Oh wait, we just did. There's nothing about the Chansey inside the robot class. Chansey only cares about what the value of the counter variable is!
The code so far:
var chansey;
let robots = [];
let counter = 0;
var https = "https://";
function preload() {
chansey = loadImage( https + "image.ibb.co/kZzhax/pzbykg5va9uz.png");
}
function setup() {
createCanvas(700, 600);
background(20);
for (var i = 0; i < 2; i++) {
for (var j = 0; j < 2; j++) {
robots.push(new Robot(i * 500 + 50, j * 400 + 75, 50));
}
}
}
function draw() {
background(20);
//drawing robot army.
for (let robot of robots) {
robot.drawRobot();
robot.chanseyMESSAGE();
}
fill(0,255,0);
text( counter, 300, 400);
//Chansey
image(chansey, 290, 250, 100, 100);
//button "make chansey happy"
stroke(255);
fill(0);
rect(310, 0, 60, 30);
fill(255);
textSize(15);
text("Reset", 320, 20);
}
function mousePressed() {
for (let antennas of robots) {
antennas.turnOn(mouseX, mouseY);
}
//this make Chansey happy
if (mouseX < 375 && mouseX > 315 && mouseY < 30 && mouseY > 0) {
for (let colorAntennaReset of robots) {
colorAntennaReset.b = 1;
colorAntennaReset.red = 0;
colorAntennaReset.green = 100;
colorAntennaReset.blue = 300;
//so now the chanseyMESSAGE disapear
colorAntennaReset.chanseyTURN = false;
}
}
}
class Robot {
constructor(x, y, t) {
this.x = x;
this.y = y;
this.t = t;
this.swicherX = this.x + 25 / 50 * this.t;
this.swicherY = this.y - 15 / 50 * this.t;
this.swicherRadius = (15 / 50 * this.t) / 2;
//swicher color
this.b = 0;
//roboteyes color
this.red = 0;
this.green = 100;
this.blue = 300;
//chansey inside robot class...
this.chanseyTURN = false;
}
drawRobot() {
//stick of the antenna
stroke(0, 100, 300);
line(this.x + 2.5 / 5 * this.t, this.y + this.t / 10, this.x + 2.5 / 5 * this.t, this.y - 3 / 5 * this.t);
//swicher ball turnOn
stroke(100);
fill(255, 100, this.b);
ellipse(this.x + 25 / 50 * this.t, this.y - 15 / 50 * this.t, 15 / 50 * this.t, 15 / 50 * this.t);
//robot head
stroke(0);
fill(0, 0, 150);
rect(this.x - this.t / 10, this.y + this.t / 5, 60 / 50 * this.t, this.t / 5);
fill(100);
rect(this.x, this.y, this.t, 4.5 / 5 * this.t);
//eyes
fill(this.red, this.green, this.blue);
rect(this.x + 9 / 50 * this.t, this.y + this.t / 5, this.t / 5, this.t / 10);
rect(this.x + 3.2 / 5 * this.t, this.y + 1 / 5 * this.t, this.t / 5, this.t / 10);
//mouth
line(this.x + 1 / 5 * this.t, this.y + 3 / 5 * this.t, this.x + 4 / 5 * this.t, this.y + 3 / 5 * this.t);
}
turnOn(suicidetryX, suicidetryY) {
let proxToAntenna = dist(suicidetryX, suicidetryY, this.swicherX, this.swicherY);
if (proxToAntenna < this.swicherRadius) {
if( this.b == 0 ){ // If the robot was off, but is now turning on..
counter++; // Add one to the counter.
}
//changing antenna color
this.b = 255;
// changing roboteyes color
this.red = 255;
this.green = 50;
this.blue = 0;
//making chansey ANGRY ..
this.chanseyTURN = true;
}
}
chanseyMESSAGE() {
if (this.chanseyTURN) {
fill(255);
textSize(20);
text("STOP IT", 303, 370);
} else {
//DONT SHOW THE MESSAGE
}
}
}
Does it work? Not really. For one, the reset button doesn't reset the counter. Each robot is displaying it's own Chansey message. And we can use the counter to determine if Chansey is angry.
Next, #3: A counter for robot switches.
First, you will need a counter variable to remember the count in:
let counter = 0
When does this count increase? When a robot's antenna switches from off to on:
// ... In the Robot class...
turnOn(suicidetryX, suicidetryY) {
let proxToAntenna = dist(suicidetryX, suicidetryY, this.swicherX, this.swicherY);
if (proxToAntenna < this.swicherRadius) {
if( this.b == 0 ){ // If the robot was off, but is now turning on..
counter++; // Add one to the counter.
}
//changing antenna color
// ...
Of course an unseen counter is not helpful for debugging it, so let's draw the counter on screen too.
// ...
robot.chanseyMESSAGE();
}
fill(0,255,0);
text( counter, 300, 400);
//Chansey
// ...
This is one of my first projects, and I have a 3 problem that I can´t resolve! This code, draws four robots and its antennas, and there is a Chansey (a pokemon), in the middle of the canvas, she gets mad if you turnOn the robots switchers.
My First problem is, I don´t know if there is a way to make a Chansey Class, because I don´t feel right with her in the Robot Class. The problem is, that she needs the information of the "turn on" behaviour.
My Second problem is that I can´t remove the chanseyMessage(); once that the user reset the robots. (there is a try, but it didnt work).
And my last problem, I don´t know how to make a local counter for the antennas. When the four antennas are on, something is going to happen Hehe.
var chansey;
function preload() {
chansey = loadImage("https://"+"image.ibb.co/kZzhax/pzbykg5va9uz.png");
}
let robots = [];
function setup() {
createCanvas(700, 600);
background(20);
for (var i = 0; i < 2; i++) {
for (var j = 0; j < 2; j++) {
robots.push(new Robot(i * 500 + 50, j * 400 + 75, 50));
}
}
}
function draw() {
//drawing robot army.
for (let robot of robots) {
robot.drawRobot();
robot.chanseyMESSAGE();
}
//Chansey
image(chansey, 290, 250, 100, 100);
//button "make chansey happy"
stroke(255);
fill(0);
rect(310, 0, 60, 30);
fill(255);
textSize(15);
text("Reset", 320, 20);
}
function mousePressed() {
for (let antennas of robots) {
antennas.turnOn(mouseX, mouseY);
}
//this make Chansey happy
if (mouseX < 375 && mouseX > 315 && mouseY < 30 && mouseY > 0) {
for (let colorAntennaReset of robots) {
colorAntennaReset.b = 1;
colorAntennaReset.red = 0;
colorAntennaReset.green = 100;
colorAntennaReset.blue = 300;
//so now the chanseyMESSAGE disapear
colorAntennaReset.chanseyTURN = false;
}
}
}
class Robot {
constructor(x, y, t) {
this.x = x;
this.y = y;
this.t = t;
this.swicherX = this.x + 25 / 50 * this.t;
this.swicherY = this.y - 15 / 50 * this.t;
this.swicherRadius = (15 / 50 * this.t) / 2;
//swicher color
this.b = 0;
//roboteyes color
this.red = 0;
this.green = 100;
this.blue = 300;
//chansey inside robot class...
this.chanseyTURN = false;
}
drawRobot() {
//stick of the antenna
stroke(0, 100, 300);
line(this.x + 2.5 / 5 * this.t, this.y + this.t / 10, this.x + 2.5 / 5 * this.t, this.y - 3 / 5 * this.t);
//swicher ball turnOn
stroke(100);
fill(255, 100, this.b);
ellipse(this.x + 25 / 50 * this.t, this.y - 15 / 50 * this.t, 15 / 50 * this.t, 15 / 50 * this.t);
//robot head
stroke(0);
fill(0, 0, 150);
rect(this.x - this.t / 10, this.y + this.t / 5, 60 / 50 * this.t, this.t / 5);
fill(100);
rect(this.x, this.y, this.t, 4.5 / 5 * this.t);
//eyes
fill(this.red, this.green, this.blue);
rect(this.x + 9 / 50 * this.t, this.y + this.t / 5, this.t / 5, this.t / 10);
rect(this.x + 3.2 / 5 * this.t, this.y + 1 / 5 * this.t, this.t / 5, this.t / 10);
//mouth
line(this.x + 1 / 5 * this.t, this.y + 3 / 5 * this.t, this.x + 4 / 5 * this.t, this.y + 3 / 5 * this.t);
}
turnOn(suicidetryX, suicidetryY) {
let proxToAntenna = dist(suicidetryX, suicidetryY, this.swicherX, this.swicherY);
if (proxToAntenna < this.swicherRadius) {
//changing antenna color
this.b = 255;
// changing roboteyes color
this.red = 255;
this.green = 50;
this.blue = 0;
//making chansey ANGRY ..
this.chanseyTURN = true;
}
}
chanseyMESSAGE() {
if (this.chanseyTURN) {
fill(255);
textSize(20);
text("STOP IT", 303, 370);
} else { //DONT SHOW THE MESSAGE }
}
}
I post it in the wrong place the first tme.
Okay, I ran gotoloops code here:-https://forum.processing.org/two/discussion/15674/speed-of-screenshots. I works, so I guess I now have robot class working. Thanks all.
As I understand it, an MCVE for what I typed would simply be import java.awt.Robot; Thats all I typed, then hit return. I'll see if I can make a robot object and get it to do something.