Processing - Make an object disappear and appear in certain frames of time - java

This is my current code:
int doorCounter = 0;
void setup()
{
size(512, 348); //width and height of screen
doorCounter = (int)random(180,300);
}
void draw()
{
display();
doorCounter = doorCounter - 1; // Decrease count by 1
if (doorCounter <= 0)
{
fill(255);
rect(420, 190, 55, 100); //house door outline
rect(435, 210, 25, 25, 7); // house door window
ellipse(435, 255, 8, 8); // house door handle
doorCounter = (int)random(180,480);
}
}
void display()
{
fill(255);
rect(420, 190, 55, 100); //house door outline
fill(0,0,0); // fill the following polygons in black
rect(435, 210, 25, 25, 7); // house door window
ellipse(435, 255, 8, 8); // house door handle
}
However what this code does is just makes the object disappear for a fraction of a second and just makes it reappear instantly. How do I make it so that the object stays disappeared for 3-8 seconds on a random interval just like how the object disappears every 3-8 seconds given that its still on the screen?
P.s I don't know if what I'm trying to achieve makes sense so please feel free to question.

An idea is to use a timestamp and check the time elapsed from it, something like this:
int min_time = 3000; // in ms
int max_time = 8000; // in ms
int time_frame = (int)random(min_time, max_time);
int time_stamp = 0;
boolean show_door = true;
void setup()
{
size(512, 348); //width and height of screen
}
void draw()
{
background(200);
int time_passed = millis() - time_stamp;
if (time_passed < time_frame && show_door) {
display();
} else if (time_passed >= time_frame) {
time_stamp = millis();
time_frame = (int)random(min_time, max_time);
show_door = !show_door;
}
}
void display()
{
fill(255);
rect(420, 190, 55, 100); //house door outline
fill(0, 0, 0); // fill the following polygons in black
rect(435, 210, 25, 25, 7); // house door window
ellipse(435, 255, 8, 8); // house door handle
}

Related

How to make gradient on the screen of my game

This is my simple game and I need to make my background have a gradient. The blue needs to be lighter on the bottom and darker blue on the top. I need the green grass to still be in the picture. I could only make it that it has black on the top. Can someone help me with this. I am using processing
int r = 0;
int g = 0;
int b = 0;
void setup() {
size(640, 480);
changeinbackground();
}
void draw() {
changeinbackground();
drawsun();
noStroke();
strokeWeight(2);
fill(0);
}
void drawsun() {
fill(255, 255, 0);
ellipse(20, 30, 120, 120);
}
void changeinbackground() {
{
fill(0, 255, 0); // colour selected for the grass on the bottom
stroke(20, 255, 0); //green outline
rect(0, 430, 650, 55); // grass on the bottom
}
for(int i = 0; i<400; i +=10 ){
fill(r,g,i);
noStroke();
rect(0,i,640,40);
}
}

How to move this eye applet or to make it blink?

Please help me how to make this eye move or to make it blink using repaint, thread and implements runnable. I don't know where to place the right codes to make it work. Please help me guys! Thank you!
Here is the code:
import java.awt.*;
import java.applet.*;
public class Pucca extends Applet {
public Pucca(){
setSize(700, 700); }
//paint method
public void paint(Graphics g){
Color white = new Color(255,255,255);
g.setColor(white);
g.fillOval(600, 100, 125, 125); //left white fill eye
g.setColor(Color.BLA­CK);
g.drawOval(600, 100, 125, 125); // left big black line eye
g.setColor(white);
g.fillOval(700, 100, 125, 125); //right white fill eye
g.setColor(Color.BLA­CK);
g.drawOval(700, 100, 125, 125); //right big black line eye
Color blue = new Color(0, 160, 198);
g.setColor(blue);
g.fillOval(635, 130, 51, 51); // left blue fill eye
g.setColor(Color.BLA­CK);
g.drawOval(635, 130, 50, 50); // left black small line eye
g.setColor(blue);
g.fillOval(735, 130, 51, 51); // right blue fill eye
g.setColor(Color.BLA­CK);
g.drawOval(735, 130, 50, 50); // right black small line eye
g.setColor(Color.BLA­CK);
g.fillOval(650, 145, 20, 20); // left black iris
g.setColor(Color.BLA­CK);
g.fillOval(750, 145, 20, 20); // right black iris
}
}
When it comes to animation, everything becomes variable. You also have a lot of repeated code (seriously, if you can paint one eye, you can paint lots).
The first thing you need to is make all the values of the eye as variable as possible.
The follow makes the eye size and position variable and the iris and pupil a scaled value of the eye size, which makes the whole process simpler to animate.
Next, you need an updated loop, which can update the state of the values you want to change. To keep it simple, I've set it up so that the pupil has a variable offset, which is changed over time.
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
public class Pucca extends Applet {
public Pucca() {
setSize(700, 700);
Thread t = new Thread(new Runnable() {
private int xDelta = -1;
private int yDelta = 0;
private int blinkCount = 0;
#Override
public void run() {
while (true) {
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
xOffset += xDelta;
double irisSize = eyeSize.width * irisScale;
double range = ((eyeSize.width - irisSize) / 2);
if (xOffset <= -range) {
xOffset = -(int) range;
xDelta *= -1;
} else if (xOffset >= range) {
xOffset = (int) range;
xDelta *= -1;
}
blinkCount++;
if (blink && blinkCount > 10) {
blink = false;
blinkCount = 0;
} else if (blinkCount > 25) {
blink = true;
blinkCount = 0;
}
repaint();
}
}
});
t.setDaemon(true);
t.start();
}
private boolean blink = false;
private int xOffset, yOffset = 0;
private Dimension eyeSize = new Dimension(125, 125);
private Point left = new Point(20, 20);
private Point right = new Point(left.x + 100, left.y);
private double irisScale = 0.4;
private double pupilScale = 0.16;
//paint method
#Override
public void paint(Graphics g) {
super.paint(g);
paintEye(g, new Rectangle(left, eyeSize));
paintEye(g, new Rectangle(right, eyeSize));
}
protected void paintEye(Graphics g, Rectangle bounds) {
Color white = new Color(255, 255, 255);
if (blink) {
g.setColor(Color.YELLOW);
} else {
g.setColor(white);
}
g.fillOval(bounds.x, bounds.y, bounds.width, bounds.height); //left white fill eye
g.setColor(Color.BLACK);
g.drawOval(bounds.x, bounds.y, bounds.width, bounds.height); // left big black line eye
if (!blink) {
Color blue = new Color(0, 160, 198);
paintEyePartAt(g, bounds, irisScale, blue);
paintEyePartAt(g, bounds, pupilScale, Color.BLACK);
}
}
private void paintEyePartAt(Graphics g, Rectangle bounds, double delta, Color color) {
int width = (int) (bounds.width * delta);
int height = (int) (bounds.height * delta);
g.setColor(color);
g.fillOval(
xOffset + bounds.x + ((bounds.width - width) / 2),
yOffset + bounds.y + ((bounds.height - height) / 2),
width, height); // left blue fill eye
g.setColor(Color.BLACK);
g.drawOval(
xOffset + bounds.x + ((bounds.width - width) / 2),
yOffset + bounds.y + ((bounds.height - height) / 2),
width,
height); // left blue fill eye
}
}
This complicates things, as painting can occur for any number of reasons, many of which you don't have control over or will be notified about, so you should be very careful about where and when you change values.
You should also have a look at Java Plugin support deprecated and Moving to a Plugin-Free Web and Why CS teachers should stop teaching Java applets.
Applets are simply a dead technology and given the inherent complexities involved in using them, you should instead focus you should probably attention towards window based programs.
Personally, I'd start with having a look at Painting in AWT and Swing and Performing Custom Painting

Refresh text in Applet

I am doing this small race between two cars, in a java applet.
Just two pictures moving at random speed. I am calculating the distance between current position and the finish line, and you are suppose to be able to see the distance in the upper corner.
The thing is I am not able to refresh the text field, instead it just applies a new layer on top of the old number so it is almost impossible to read.
Here are pictures to demonstrate my problem.
I thought I would be able to solve it by creating the blue rectangle at the start of each loop but that does not seem to solve it.
public void action(){
Random rand = new Random();
boolean race = true;
int x1 =500, y1 = 233;
int x2 = 500, y2 = 333;
int speed1 = rand.nextInt(15) + -16;
int speed2 = rand.nextInt(15) + -16;
int finishline = 30;
Text winnerBlue = new Text("Winner: BLUE",new Font("SansSerif",Font.BOLD,20), Color.blue,Color.white);
Text winnerRed = new Text("Winner: RED",new Font("SansSerif",Font.BOLD,20), Color.red,Color.white);
//background
Text text =null;
Text text2 = null;
window.fillRect(0, 0, 600, 400, Color.GREEN);
//track 1
window.fillRect(20, 330, 550, 39, Color.gray);
//track2
window.fillRect(20, 230, 550, 39, Color.gray);
//Finish line
window.fillRect(40, 210, 10, 180, Color.BLACK);
while(race){
text = new Text(Integer.toString(x1),new Font("Courier",Font.BOLD,20), Color.WHITE);
text2 = new Text(Integer.toString(x2),new Font("SansSerif",Font.BOLD,20), Color.WHITE);
window.fillRect(0, 0, 70, 50, Color.blue);
window.fillRect(70, 0, 70, 50, Color.red);
window.showImage(text, 0, 0);
window.showImage(text2, 70, 0);
window.showImage(car1.getImage(), x1, y1);
window.showImage(car2.getImage(), x2, y2);
car1.moveTo(x1 += speed1, y1);
car2.moveTo(x2 += speed2, y2);
window.pause(50);
if(x1 <= (finishline ) ){
speed1 = 0;
speed2 = 0;
window.showImage(winnerBlue, 200, 200);
race = false;
}
if(x2 <= (finishline)){
speed2 = 0;
speed1 = 0;
window.showImage(winnerRed, 200, 200);
race = false;
}
}
}
}
For the two screen shots and supplied code snippt, it's clear that you don't understand how painting works in Swing/AWT.
Do NOT ever, maintain any kind of refernce to the Graphics context out side of the paintXxx methods.
The paint methods perform a number of very important steps to prepare the Graphics context for painting
Start by taking a look through Performing Custom Painting

Why is this error showing up? — Processing

Could anyone share with me why I am getting this error? Basically it's a program where I want to simulate basic basic plant growth. I want to do it in such a way that the petals are all stored in an array of circles.
Stem myStem;
Circle circles;
float scaleFactor=0.5;
void setup() {
size(floor(400*scaleFactor), floor(800*scaleFactor));
myStem = new Stem(200,800);
}
void draw() {
background(150);
smooth();
Circle circles[];
circles = new Circle[5];
circles[0] = new Circle(0, -40, 50, 50);
circles[1] = new Circle(0, -40, 50, 50);
circles[2] = new Circle(0, -40, 50, 50);
circles[3] = new Circle(0, -40, 50, 50);
circles[4] = new Circle(0, -40, 50, 50);
for (int i = 0; i < circles.length; i++) {
circles = ellipse(circles[i].c1, circles[i].c2, circles[i].c3, circles[i].c4);
rotate(radians(72));
circles[i] = Circle;
}
myStem.drawStem();
}
class Stem {
int initalloX=200;
int initalloY=800;
Stem(int tempInitalloX, int tempInitalloY) {
initalloX = tempInitalloX;
initalloY = tempInitalloY;
}
void drawStem() {
background(#0DBADB);
scale(scaleFactor, scaleFactor);
stroke (12, 149, 11);
fill (12, 149, 11);
strokeWeight(10);
line(initalloX, initalloY, initalloX, ((frameCount>250)?initalloY-500:initalloY-(2*frameCount)));
//stem1
if (frameCount>101) {
noStroke();
translate(initalloX, initalloY-200);
scale(min((float)(frameCount-100)/100, 1), min((float)(frameCount-100)/100, 1));
beginShape();
vertex(0, 0);
bezierVertex(-40, -5, -30, -40, -80, -20);
bezierVertex(-47, -16, -52, 8, 0, 0);
endShape(CLOSE);
scale(1/min((float)(frameCount-100)/100, 1), 1/min((float)(frameCount-100)/100, 1));
translate(-initalloX, -(initalloY-200));
}
//stem2
if (frameCount>151) {
noStroke();
translate(initalloX, initalloY-300);
scale(-min((float)(frameCount-150)/150, 1), min((float)(frameCount-150)/150, 1));
beginShape();
vertex(0, 0);
bezierVertex(-40, -5, -30, -40, -80, -20);
bezierVertex(-47, -16, -52, 8, 0, 0);
endShape(CLOSE);
scale(-1/min((float)(frameCount-150)/150, 1), 1/min((float)(frameCount-150)/150, 1));
translate(-initalloX, -(initalloY-300));
}
}
}
class Circle {
int c1 = 0;
int c2 = -40;
int c3 = 50;
int c4 = 50;
Circle(int tc1, int tc2, int tc3, int tc4) {
c1 = tc1;
c2 = tc2;
c3 = tc3;
c4 = tc4;
}
}
Thanks in advance... All help is much appreciated.
Besides all thing already pointed, note that ellipse() is a void method, and so, it won't return anything. Thus a line like
circle = ellipse(x,y,z,z)
has no meaning. You probably wan to use the values stored in ciclcle[i] to draw ellipses, so just call
ellipse(circles[i].c1, circles[i].c2, circles[i].c3, circles[i].c4);
no need for assigning it. Also i don't see why create 5 equal circles. If your circle object is just storing data, why store the same data five times? The call:
for (int i = 0; i < circles.length; i++) {
ellipse(0, -40, 50, 50);
rotate(radians(72));
}
Will have the same effect.
Besides that calling background() at the end of draw (trough myStem.drawStem()) will hide all things previously drawn.
And yet there is no need to recreate the array and reassign the values 60 times per second, you can move it to setup.
I made those changes to your code. It will compile now. Still the "petals" is beeing drawn at origin, and the fill/stroke of them needs to be handled, but at least it is running :)
You may want to make a display method in your circle class... More like i pointed in the other post you made. cheers!
Stem myStem;
//Circle circles; // double declaration
Circle circles[]; // keeping the array one only
float scaleFactor=0.5;
void setup() {
size(floor(400*scaleFactor), floor(800*scaleFactor));
myStem = new Stem(200,800);
//mpoved this to setup, no need to recreate each frame
circles = new Circle[5];
circles[0] = new Circle(0, -40, 50, 50);
circles[1] = new Circle(0, -40, 50, 50);
circles[2] = new Circle(0, -40, 50, 50);
circles[3] = new Circle(0, -40, 50, 50);
circles[4] = new Circle(0, -40, 50, 50);
// also smooth only needs to be called once
// unless ther is a noSmooth() somewhere
smooth();
}
void draw() {
// moved this here
background(#0DBADB);
for (int i = 0; i < circles.length; i++) {
ellipse(circles[i].c1, circles[i].c2, circles[i].c3, circles[i].c4);
// note you may use this instead
//ellipse(0, -40, 50, 50);
rotate(radians(72));
}
myStem.drawStem();
}
class Stem {
int initalloX=200;
int initalloY=800;
Stem(int tempInitalloX, int tempInitalloY) {
initalloX = tempInitalloX;
initalloY = tempInitalloY;
}
void drawStem() {
//background(#0DBADB); // this was hiding all other draws
scale(scaleFactor, scaleFactor);
stroke (12, 149, 11);
fill (12, 149, 11);
strokeWeight(10);
line(initalloX, initalloY, initalloX, ((frameCount>250)?initalloY-500:initalloY-(2*frameCount)));
//stem1
if (frameCount>101) {
noStroke();
translate(initalloX, initalloY-200);
scale(min((float)(frameCount-100)/100, 1), min((float)(frameCount-100)/100, 1));
beginShape();
vertex(0, 0);
bezierVertex(-40, -5, -30, -40, -80, -20);
bezierVertex(-47, -16, -52, 8, 0, 0);
endShape(CLOSE);
scale(1/min((float)(frameCount-100)/100, 1), 1/min((float)(frameCount-100)/100, 1));
translate(-initalloX, -(initalloY-200));
}
//stem2
if (frameCount>151) {
noStroke();
translate(initalloX, initalloY-300);
scale(-min((float)(frameCount-150)/150, 1), min((float)(frameCount-150)/150, 1));
beginShape();
vertex(0, 0);
bezierVertex(-40, -5, -30, -40, -80, -20);
bezierVertex(-47, -16, -52, 8, 0, 0);
endShape(CLOSE);
scale(-1/min((float)(frameCount-150)/150, 1), 1/min((float)(frameCount-150)/150, 1));
translate(-initalloX, -(initalloY-300));
}
}
}
class Circle {
int c1 = 0;
int c2 = -40;
int c3 = 50;
int c4 = 50;
Circle(int tc1, int tc2, int tc3, int tc4) {
c1 = tc1;
c2 = tc2;
c3 = tc3;
c4 = tc4;
}
}
Learned something new I guess for declaring an array.
As for what is going wrong, it looks like you're using a Circle variable called "circle" and confusing it with an array of Circles by also calling it circle which probably is leading to all sorts of problems. That's probably what you should focus on fixing.
Guessing...
There are two definitions of circles in the class
Circle circles
Circle[] circles
I think this circles[i] = Circle; is the error. You cannot asign a Type (the class Circle) to a variable (i.e. an Object or an instance of a class)

Java House Applet

So I'm just starting with Applets and I am making a house with an open door and 2 open windows when the applet loads. When you click these windows or door then they will shut. My question though is what do I need to do to re-open these windows doors. I figure I need to set the Boolean variables to False somehow and repaint. Where would I do this. I don't need you guys to write the code for me, I just want to know what I should do.
Thanks ahead of time,
Rick
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/**
Rick Armstrong
Chapter 14 - House Applet
*/
public class HouseApplet extends Applet {
boolean leftWin, rightWin, door;
public void init()
{
leftWin = false;
rightWin = false;
door = false;
setBackground(Color.white);
addMouseListener(new MyMouseListener());
}
public void paint(Graphics g)
{
super.paint(g);
// Draw the house.
g.setColor(Color.black);
g.drawRect(100, 100, 200, 100);
// Draw the roof
g.drawLine(80, 100, 320, 100);
g.drawLine(80, 100, 200, 40);
g.drawLine(200, 40, 320, 100);
// Draw the left window open.
g.fillRect(120, 130, 40, 40);
// Draw the right window open.
g.fillRect(240, 130, 40, 40);
// Draw the door open.
g.fillRect(180, 130, 40, 70);
if (leftWin) {
// Draw the left window closed.
g.setColor(Color.white);
g.fillRect(120, 130, 40, 40);
g.setColor(Color.black);
g.drawRect(120, 130, 40, 40);
g.drawLine(140, 130, 140, 170);
g.drawLine(120, 150, 160, 150);
}
if (rightWin) {
// Draw the right window closed.
g.setColor(Color.white);
g.fillRect(240, 130, 40, 40);
g.setColor(Color.black);
g.drawRect(240, 130, 40, 40);
g.drawLine(260, 130, 260, 170);
g.drawLine(240, 150, 280, 150);
}
if (door) {
// Draw the door closed.
g.setColor(Color.white);
g.fillRect(180, 130, 40, 70);
g.setColor(Color.black);
g.drawRect(180, 130, 40, 70);
g.fillOval(210, 165, 07, 07);
}
}
private class MyMouseListener implements MouseListener
{
public void mousePressed(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
int currentx = e.getX();
int currenty = e.getY();
boolean WindowLeft = (currentx >= 120 && currentx < 160 && currenty >= 130 && currenty <= 170);
if (WindowLeft)
{
leftWin = true;
repaint();
}
boolean WindowRight = (currentx >= 240 && currentx < 280 && currenty >= 130 && currenty <= 170);
if (WindowRight)
{
rightWin = true;
repaint();
}
boolean Door = (currentx >= 180 && currentx < 220 && currenty >= 40 && currenty <= 200);
if (Door)
{
door = true;
repaint();
}
else;
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
}
}
Maybe I'm misunderstanding the question, but why are you always setting the values to true in the event handler?
If you want a toggling behavior, you could simply write: value = !value and then repaint.
Since you initially set your value to false, the next click would set it to true, the next to false, etc. etc.
For example:
if (WindowLeft)
{
leftWin = !leftWin;
repaint();
}
Note that it is possible for you to cause sort of a "race condition" by clicking faster than the framework has a chance to update the view, but this is usually not a problem for initial problem.
BTW: In terms of readability, consider naming your variables in a way that conveys their meaning. For example, is the naming door evocative of a boolean? not really. but doorOpen is, and it helps interpret the meaning of the variable and its transitions.
if (WindowRight)
{
rightWin = false;
repaint();
}
else {
rightWin = true;
repaint();
}
try the above. When you click inside the window, it closes otherwise it opens

Categories

Resources