In processing, I need to fill a screen with rectangles based on its height. However, the code below is giving me a white screen. Anyone know why?
void setup (){
size (600,600);
background (255);
fill (200,200,200);
noStroke();
}
int y = 10;
int spatie = 20;
int stop = height;
void draw(){
while(y < stop) {
rect (50,y,100,10);
y = y + spatie;
}
}
Your drawing loop is correct
void draw(){
while(y < stop) {
rect (50,y,100,10);
y = y + spatie;
}
}
but you cannot see rectangles because of other mistake.
When Processing object is intantiated all its fields (like y, spatie, stop in your case) are initialized. At this time variable height is set to 0 as screen height is unknown.
Next setup() is called and from this time height has value. But stop has value assigned at initialization phase. Next draw() is called in animation thread, but stop variable is frozen to value 0.
Consider these small examples:
int stop = height;
public void setup() {
size(800,600);
}
public void draw() {
println("stop = " + stop);
}
and:
int stop;
public void setup() {
size(800,600);
stop = height;
}
public void draw() {
println("stop = " + stop);
}
First will output: stop = 0
Second will print: stop = 600
Just ran your code and it is showing me 5 grey rectangles:
So to achive rectangles unti the end of the screen, maybe use
for (int y = 0; y < height / spatie; y++) {
rect (50, y * spatie, 100, 10);
}
Just set up you're sketch and only removed int stop = height; and changed your while loop a bit (use height and use height instead of stop)
If you run the following code, it should work:
void setup(){
size (600,800);
background (255);
fill (200,200,200);
noStroke();
noLoop();
}
int y = 10;
int spatie = 20;
void draw(){
while(y<height){
println(y);
rect(50,y,100,10);
y = y + spatie;
}
}
Related
Im new to programming and I'm making a aim trainer game where you hit different circles and have to hit one before it changes to the next circle. I having some trouble though. I can't figure out how to make a hitbox for the circles that change for each circle and how to increase the score.
The code is in open processing in pjs.
class Timer {
int time;
int duration;
Timer() {
duration = 100;
reset();
}
void reset() {
time = millis() + duration;
}
boolean alarm() {
if ( millis() > time ) {
time = millis() + duration;
return true;
}
return false;
}
}
float x,y,s; //size and position of circles
color c; //colour of circles
int score = 0; //score
int miss = 0; //misses
Timer timer = new Timer();
void setup() {
size(700, 500);
timer.duration = 2000; //changes the circle every 2 seconds
missed =+ 1;
newEllipse(); // Make initial circle.
}
void draw() {
background(100);
fill(c);
text("SCORE: " + str(score),620,20);
text("MISSED: " + str(miss),20,20);
ellipse(x, y, s, s);
if( timer.alarm() ){
newEllipse();
}
}
void mousePressed(){
if( overEllipse() ){
score =+1;
newEllipse();
}
}
boolean overEllipse(){
if(mouseX > x && mouseX < x+s && mouseY > y && mouseY < y + s);
}
void newEllipse() {
s = random(5,min(50,50));
x = random(0, width - s);
y = random(0, height - s);
c = color( random(255), random(255), random(255) );
timer.reset();
}
Once I tried your code I realized that you were going for something very simple, so no need for OOP today. I fixed and commented your code so you can tweak it and test stuff:
float s; //size of circles
PVector targetPosition; // position of target
color c; //colour of circles
int score = 0; //score
int miss = 0; //misses
Timer timer = new Timer();
void setup() {
size(700, 500);
timer.duration = 2000; //changes the circle every 2 seconds
newEllipse(); // Make initial circle.
}
void draw() {
background(100);
fill(255); // easier to read if you don't change the color all the time
text("SCORE: " + str(score), 620, 20);
text("MISSED: " + str(miss), 20, 20);
fill(c);
ellipse(targetPosition.x, targetPosition.y, s, s);
if ( timer.alarm() ) {
miss += 1; // added a 'miss' when the user isn't able to click the target in due time
newEllipse();
}
}
// notice that I switched this method for 'mouseClicked' instead of 'mousePressed'
// the difference is that this works on a simple click, and run once per click instead of continuously
void mouseClicked() {
if (overEllipse()) {
score += 1;
newEllipse();
} else { // added a 'miss' when the user clicks at random
miss += 1;
}
}
boolean overEllipse() {
// these 3 lines are giving you feedback so you know how close to the target you were
PVector mousePosition = new PVector(mouseX, mouseY);
println(mousePosition.dist(targetPosition) + " / " + s/2);
// you only need the next line if you don't care about the feedback
return mousePosition.dist(targetPosition) < s/2;
}
void newEllipse() {
s = random(10, 50); // I removed the `min(50,50)` because the minimum number between 50 and 50 is... 50. Maybe you were going for something else, but like this it was not needed
targetPosition = new PVector(random(s/2, width - s/2), random(s/2, height - s/2));
c = color( random(255), random(255), random(255) );
timer.reset();
}
class Timer {
int time;
int duration;
Timer() {
duration = 100;
reset();
}
void reset() {
time = millis() + duration;
}
boolean alarm() {
if ( millis() > time ) {
time = millis() + duration;
return true;
}
return false;
}
}
The main problem here was that the method overEllipse made no sense, so I set it on fire and rewrote it using a PVector instead of straight coordinates. I did it mostly because it's easier than to use math to determine if we're clicking inside the target later (the PVector class will straight up do it for you, it's an awesome tool, take a look at how I tweaked the overEllipse method and how it's easy with this tool!). I also added some feedback as console println so you can know how close you clicked from the target.
I'll be around of there's something you'd like me to explain. Have fun!
My problem is wherever i click a node appears and for the second click another node appears with connected edge...so i want that When i click at any location, the node should be generated at the closest grid intersection point. I tried using loops.
and i'm trying to do that without "class"
int n_partition=10;
int length = 101;
PVector[] position = new PVector[length];
int BallNum;
void setup() {
size(600, 360);
background(255);
}
void draw() {
fill(255);
grid();
fill(0);
}
void mousePressed(){
stroke(0);
BallNum++;
position[BallNum]= new PVector(mouseX, mouseY);
circle(position[BallNum].x, position[BallNum].y, 10);
if (BallNum > 1) {
line(position[BallNum].x,position[BallNum].y,position[BallNum-
1].x,position[BallNum-1].y);
line(position[1].x,position[1].y,position[BallNum].x,position[BallNum] .y);
}
for (int i = 0; i < position[BallNum].length; ++ i) {
position[BallNum] = position[BallNum].get(i);
position[BallNum] = position[BallNum].get((i+1) % position[BallNum].length);
line(position[BallNum].x, position[BallNum].y,
position[BallNum].x, position[BallNum].y);
}
}
I EXPECT THE NODE SHOULD GO TO THE CLOSEST INTERSECTION.
You've to calculate the nearest position of the mouse to a point on the grid. For that you've to know the width (tile_width) and the height (tile_height) of cell.
The index of the cell can be calculated by the dividing the mouse position to the size of a tile and round() the result to an integral value (e.g. round(mouseX / (float)tile_width)).
Don't draw anything in int the mousePressed callback. The only thing you've to do there is to add a pint to the list:
void mousePressed(){
int tile_width = width / n_partition; // adapt this for your needs
int tile_height = height / n_partition;
int x = round(mouseX / (float)tile_width) * tile_width;
int y = round(mouseY / (float)tile_height) * tile_height;
position[BallNum]= new PVector(x, y);
BallNum++;
}
All the drawing has to be done in draw(). Draw the lines and points in separate loops:
void draw() {
background(255);
grid();
// draw the lines in a loop
strokeWeight(3);
stroke(0, 0, 255);
for (int i = 0; i < BallNum; ++ i) {
int i2 = (i+1) % BallNum;
line(position[i].x, position[i].y, position[i2].x, position[i2].y);
}
// draw balls in a loop
strokeWeight(1);
stroke(0, 0, 0);
fill (255, 0, 0);
for (int i = 0; i < BallNum; ++i) {
circle(position[i].x, position[i].y, 10);
}
}
Note, the scene is consecutively redrawn in every frame. Before the scene is drawn, the entire window has to be "cleared" by background().
See the result:
A program I'm modifying is supposed to use a drawing panel to randomly move a square, starting from the center, either left or right and use an array to tally the position it moves to while the square stays on screen (the panel is 400 x 400 and the square is 10 x 10, so there are only 40 possible positions it can move to) After the square goes off screen, I have to print a histogram that shows how many times the square moved to that index (i.e if the square moved from the x coordinate of 200 to 190, index 19 would get a tally) Here is my code:
import java.awt.*;
import java.util.*;
public class RandomWalkCountSteps {
// DrawingPanel will have dimensions HEIGHT by WIDTH
public static final int HEIGHT = 100;
public static final int WIDTH = 400;
public static final int CENTER_X = WIDTH / 2;
public static final int CENTER_Y = HEIGHT / 2;
public static final int CURSOR_DIM = 10;
public static final int SLEEP_TIME = 25; // milliseconds
public static void main( String[] args ) {
DrawingPanel panel = new DrawingPanel( WIDTH, HEIGHT );
Random rand = new Random();
walkRandomly( panel, rand );
}
public static void walkRandomly( DrawingPanel panel, Random rand ) {
Graphics g = panel.getGraphics();
int[] positionCounts = new int[ WIDTH / CURSOR_DIM ];
// start in center of panel
int x = CENTER_X;
int y = CENTER_Y;
// Draw the cursor in BLACK
g.fillRect(x, y, CURSOR_DIM, CURSOR_DIM);
// randomly step left, right, up, or down
while ( onScreen( x, y ) ) {
panel.sleep( SLEEP_TIME );
// Show a shadow version of the cursor
g.setColor(Color.GRAY);
g.fillRect(x, y, CURSOR_DIM, CURSOR_DIM);
if ( rand.nextBoolean() ) { // go left
x -= CURSOR_DIM;
}
else { // go right
x += CURSOR_DIM;
}
positionCounts[ x / CURSOR_DIM ]++;
histogram(positionCounts, x, y);
// draw the cursor at its new location
g.setColor(Color.BLACK);
g.fillRect(x, y, CURSOR_DIM, CURSOR_DIM);
}
}
public static boolean onScreen( int x, int y ) {
return 0 <= x && x < WIDTH
&& 0 <= y && y < HEIGHT;
}
public static void histogram(int[] positionCounts, int x, int y) {
if (onScreen(x, y) == false) {
for (int i = 0; i < WIDTH / CURSOR_DIM; i++) {
System.out.print(i + ": ");
for (int j = 1; j <= positionCounts[i]; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
}
My problem was that I couldn't find a good place to initialize the array so that it wouldn't re-initialize every time I passed the x coordinate to the histogram method. Now that I thought I had it in the right place, I get this error message on both calls to histogram in the method walkRandomly "error: method histogram in class RandomWalkCountSteps cannot be applied to given types;" I'm fairly new to java and programming in general, so there's probably something I'm missing regarding arrays as parameters. Thanks in advance.
histogram takes two parameters, positionCounts of type int[] and x of type int. In walkRandomly, you call histogram twice: once with an argument positionCounts of type int[] and once with an argument x of type int. That’s why the compiler complains that the method ”cannot be applied to given types”: the method histogram(int[], int) can’t be applied to (called with) the given types, i.e., histogram(int[]) and histogram(int).
I’m not sure what you’re trying to do with this code, but I’d guess that you want remove the first call and change the second call (inside of the while loop) to histogram(positionCounts, x).
(You’ve edited your code, so my answer doesn’t make much sense.)
I am trying to make a program that generates 25 random ovals then draw a ball and make it bounce, I got it somewhat done, I generated the ovals and I got the ball to move but when I added the thread it kept repeating the draw oval loop, I get somewhat why this is happening but I have no idea how to fix it.
Basically my program should:
draw 25 random sized ovals on random locations within the border - completed
draw a ball and make it move - completed
make the ball bounce - not done but I know how to do it
but it keeps repeating step one.
this is my code that I have written, oh and I have to use applets right now its part of the course please don't suggest I use swing or something else:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
public class As4B extends Applet implements Runnable
{
public int x, y;
public int width = 854;
public int height = 480;
public int border = 20;
public Image offscreen;
public Graphics d;
public void init()
{
setSize(width,height);
Thread th = new Thread(this);
th.start();
offscreen = createImage(width,height);
d = offscreen.getGraphics();
}
public void run()
{
x = 100;
y = 100;
while(true)
{
x ++;
y ++;
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void paint(Graphics gfx)
{
d.setColor(java.awt.Color.black);
d.fillRect(0, 0, width, height);
d.setColor(java.awt.Color.green);
d.fillRect(0 + border, 0 + border, (width - (border * 2)), (height - (border* 2)));
genOval(25, d);
d.setColor(Color.gray);
d.fillOval(x, y, 50, 50);
gfx.drawImage(offscreen, 0, 0, this);
}
public int random(int low, int high)
{
int answer =(int)((Math.random()*(high-low))+ low);
return answer;
}
public void genOval(int amount, Graphics f)
{
int ranWidth, ranHeight, ranX, ranY, red, blue, green;
int i = 0;
while(i < 25)
{
green = random(0,255);
blue = random(0,255);
red = random(0,255);
f.setColor(new Color(red,green,blue));
ranWidth = random(30,400);
ranHeight = random(30,200);
ranX = random(0 + border, ((width - border)- (ranWidth)));
ranY = random(0 + border , ((height - border)- (ranHeight)));
f.fillOval(ranX, ranY, ranWidth, ranHeight);
i++;
}
}
public void update(Graphics gfx) {
paint(gfx);
}
}
Your genOval() method has no persistent backing. Every time repaint() is called (by your thread), the paint() method is called, and this generates new locations for the random ovals. You need to create a persistent source for that information, like so:
List<Rectangle> rectangles = new ArrayList<Rectangle>();
List<Color> colors = new ArrayList<Color>();
public void init() {
...
for (int i = 0; i < 25; i++) {
int green = random(0,255);
int blue = random(0,255);
int red = random(0,255);
colors.add(new Color(red,green,blue));
ranWidth = random(30,400);
ranHeight = random(30,200);
ranX = random(0 + border, ((width - border)- (ranWidth)));
ranY = random(0 + border , ((height - border)- (ranHeight)));
rectangles.add(new Rectangle(ranX, ranY, ranWidth, ranHeight));
}
}
public void genOval(Graphics g) {
for (int i = 0; i < 25; i++) {
Color color = colors.get(i);
Rectangle rectangle = rectangle.get(i);
// Draw using color & rectangle
}
}
Before I ask my question I apologize for any inconsistencies. I´m fairly new at this.
I´m making a game that for now looks like this (the picture is not important):
The red dots are supposed to move to the right and they do that with a timer. This works fine. The graphics does not update though so I have to drag the side of the window back and forth to see that my dots are moving. What can I do to fix this?
My paintcomponent method in my mainclass:
public void paintComponent(Graphics g){
super.paintComponent(g);
for (int x = 0; x < SomeInts.amount; x++){
for (int y = 0; y < SomeInts.amount; y++){
tile[x][y].colorBody(g, x, y);
Tower temp;
for (int i = 0; i < towers.size(); i++){
temp = towers.get(i);
temp.colorBody(g, tile[x][y].getSize());
temp.guard.colorBody(g, tile[x][y].getSize());
}
}
}
}
My red dot class. Also called Guard class:
public class Guard {
int x, y, size = 10, towerx, towery;
Timer timer;
public Guard(int towerx1, int towery1){
towerx = towerx1;
towery = towery1;
x = towerx + 1;
y = towery;
new Timer().schedule(new MyTask(), 1000, 1000);
}
public void colorBody(Graphics g, int tilesize){
g.setColor(new Color(255, 0, 0));
g.fillOval(x * tilesize + tilesize / 4, y * tilesize + tilesize / 4, size, size);
}
public class MyTask extends TimerTask {
public void run() {
x++;
}
}
}
Thank you for your time.
I'm guessing a bit here, but I think you need to call the repaint() method to see the changes you've made.