this code is supposed to have an ellipse with a "trail" of ellipses behind it that decrease in size and become more white. It is called "Smoke Trail" and the ellipses in this code work properly for the most part. There is one problem in the code where one of the ellipses draws over the trail and doesn't go behind like all the others. I think it has something to do with the first or last ellipse of the for loop
int count = 75;
int made = 0;
Smokes[] arrSmokes = new Smokes[count];
void setup()
{
size(800, 800);
}
void draw()
{
background(255);
if(made < count)
{
arrSmokes[made] = new Smokes();
made += 1;
}
for(int i = 0; i < made; i += 1)
{
arrSmokes[i].render();
}
}
public class Smokes{
int xCoord, yCoord;
float size;
Smokes()
{
xCoord = mouseX;
yCoord = mouseY;
size = 100;
}
void render()
{
noStroke();
ellipse(xCoord, yCoord, size, size);
size -= 4;
if(size <= 0)
{
xCoord = mouseX;
yCoord = mouseY;
size = 100;
}
}
}
Since you are keeping your old Instances of smoke and just reset them you have to store the top of your circles. Just use a Integer for that.
int top = 0;
Now you have to give every circle its number in the array...
if (made < count) {
arrSmokes[made] = new Smokes(made);
made ++;
}
/*
...
*/
int number;
Smokes(int number)
{
this.number = number;
//Initialyze
}
Now you have to change the top of your list every time you reset the Smoke particle.
void reset()
{
xCoord = mouseX;
yCoord = mouseY;
c = 0;
size = 100;
top = number;
}
Your for-loop should now start at the entry one above the top and go the way up to the end of the array and then jump to the first entry and run until it reaches the top entry.
for (int i = (top+1)%count; i != top; i = (i+1)%count) {
if (i >= made) continue;
arrSmokes[i].render();
}
Since you are not allowed to change the top while executing "render();" you have to add a function "evaluate();" which you run after having done every "render();".
void evaluate()
{
c += 10.2;
size -= 4;
if (size <= 0) {
reset();
}
}
void render()
{
noStroke();
fill(c);
ellipse(xCoord, yCoord, size, size);
}
Now you should be good to go. Here is the whole source again if I messed you up a bit: https://pastebin.com/urzbzmEb
But I recommend to use a ArrayList instead since Java is object-based and has its own garbage-collector. The good thing at the ArrayList is you know at every time that the last object in the list is the top circle.
Here is how it would look like with an ArrayList.
ArrayList<Smokes> smokes = new ArrayList<Smokes>();
void setup() {
size(800, 800);
}
void draw() {
background(255);
smokes.add(new Smokes(mouseX, mouseY));
for (int i = 0; i < smokes.size(); i ++) {
smokes.get(i).render();
}
}
public class Smokes {
int xCoord, yCoord;
float size = 100, c = 0;
Smokes(int x, int y) {
xCoord = x;
yCoord = y;
}
void render() {
noStroke();
fill(c);
ellipse(xCoord, yCoord, size, size);
c += 10.2;
size -= 4;
if (size <= 0) {
smokes.remove(this);
}
}
}
Related
So I am making this game in processing JAVA and the code is below so the gist is I have a ball and it avoids the falling rectangles so, for now, the ball can move sideways and the rectangles fall from above but how do I decrease my life when a rectangle hits the ball.
I made a function named Lives which was supposed to decrease lives if the circle gets hit with a rectangle but I can't come up with the code for that. Could anyone help with that?
int score;
int score1;
int miss;
int lives=10;
int ballx, bally;
class Rect
{
float x;
float y;
float speed;
float leng;
color c;
boolean valid;
final int MAX_COLOR = 255;
final int MIN_X = 50, MAX_X = 750;
final int MIN_Y = -800, MAX_Y = -100;
int MIN_SPEED = 1, MAX_SPEED = 2;
final int MIN_Leng = 50, MAX_Leng =100 ;
Rect()
{
initAll();
}
void initAll() {
valid = true;
c = color(random(255), random(255), random(255));
x = random(MIN_X, MAX_X);
y = random(MIN_Y, MAX_Y);
speed = random(MIN_SPEED, MAX_SPEED);
leng = random(MIN_Leng, MAX_Leng);
}
void update() {
if (!valid) {
initAll();
return;
}
move();
draw_rect();
}
void draw_rect()
{
fill(c);
rect (x, y, leng, leng);
}
void move()
{
if (y-leng <= height)
{
y += speed;
} else if (y-leng > height )
{
valid = false;
miss++;
}
}
void Lives()
{
}
void GameOver()
{
if (lives==0)
{
for (int i = 0; i < Obj.length; i++)
{
Obj[i] = new Rect();
}
background(0);
textSize(50 );
fill(255);
text( "You Lose ", 15, 150);
text( "Score: " + score, 15, 100);
}
}
boolean isOver(int mx, int my) {
float disX = x - mx;
float disY = y - my;
if (sqrt(sq(disX) + sq(disY)) < leng/2 ) {
return true;
} else {
return false;
}
}
}
Rect [] Obj = new Rect [10];
void setup() {
size (400, 600);
ballx=200;
bally=300;
for (int i = 0; i < Obj.length; i++)
{
Obj[i] = new Rect();
}
}
void draw() {
background(0);
textSize(50);
//fill(0);
text( "Score: " + score, 0, 100);
text("Lives: " + lives, 0, 50);
ellipse(ballx,bally,20,20);
for (int i = 0; i < Obj.length; i++) {
Obj[i].update();
//Obj[i].Lives();
Obj[i].GameOver();
}
surface.setTitle(nf(frameRate, 3, 2));
}
void keyPressed(){
for(Rect s : Obj){
if ( key =='q' ){
ballx=ballx-2;
score++;
score1++;
s.valid = false;
break;
}
if ( key =='e'){
ballx=ballx+2;
score++;
score1++;
s.valid = false;
break;
}
}
}
Easiest i think think of is -
case 1 - if you want health of ball to reduce gradually :
Define maximum_Health variable and assign it to 100.
Every time a block hits your ball, reduce the health by some weight you want to define.
case 2 - if ball life is lost for every block hit
Define remaining_Lives variable and give it some value you want the number of lives to start with.
Every time a block hits your ball, reduce the remaining_Lives by one.
I think that should give you some hint.
I'm brand new to java and I'm making a snake game. My next step is to add a rectangle to the snake whenever it eats food. My current thinking is, I want to add an identical rectangle that's translated to the previous position of (mouseX, mouseY). At least, translated a distance of one rectangle from the previous one, but oriented where the mouse previously was, to "follow" behind the piece in front of it. I'm not sure how to go about doing that, but here is my code thus far.
//snake
void snake() {
rect(mouseX, mouseY, 10, 10);
}
class Snake {
//variables
int len;
int wid;
int xcord;
int ycord;
//constructor
Snake(int x,int y, int len, int wid) {
this.len = len;
this.wid = wid;
this.xcord = x;
this.ycord = y;
rect(xcord, ycord, wid, len);
}
//clear screen
void update() {
background(255);
rectMode(CENTER);
rect(mouseX, mouseY, wid, len);
}
}
class Food {
//variables
int xcord;
int ycord;
int wid;
int len;
//constructor
Food() {
this.xcord = int(random(width - 5));
this.ycord = int(random(height - 5));
this.wid = 10;
this.len = 10;
rect(xcord, ycord, wid, len);
}
//update food position
void update() {
if( (mouseX > xcord) && (mouseX < xcord + wid) &&
(mouseY > ycord) && (mouseY < ycord + len)) {
xcord = int(random(width - 5));
ycord = int(random(height - 5));
//lengthen snake
}
}
//display food
void displayFood() {
rect(xcord, ycord, 10, 10);
}
}
Snake s;
Food f;
void setup() {
background(255);
s = new Snake(mouseX, mouseY, 10, 10);
f = new Food();
}
void draw() {
s.update();
f.update();
f.displayFood();
}
You make 2 variables
float pMouseX = mouseX;
float pMouseY = mouseY;
Then, in draw, after updating the snake, you update those variables:
s.update
pMouseX = mouseX;
pMouseX = mouseY;
For having more than 2 rectangles, instead of single variables, consider using an ArrayList of arrays.
An Array is basically a way to store multiple variables in one variable.
An ArrayList is similar, but it doesn't have a set size. This means that you can keep adding elements to ArrayLists, which is something you can't do with Arrays.
You can declare such an ArrayList like this:
ArrayList<float[]> arrayList = new ArrayList<float[]>(); //each element of the ArrayList is an array, which contains an x and y position
To get the x and y coordinates of any rectangle, use arrayList.get(indexOfTheRectangle)[0] //use 1 instead of 0 for the y coordinate
and update them like this:
for (int i = arrayList.length - i; i > 0; i++) { //you need to go through the array backwards, because otherwise, for each element, you end up changing the value it is supposed to get, which results in all elements having the same value.
arrayList[i] = arrayList[i - 1];
}
arrayList[0] = new float[]{mouseX, mouseY}
I'm all new to this and doing a beginner's lecture on Java (with Processing). Our assignment this time is the bouncing ball. I've (sort of) successfully gotten it to move the way it's supposed to and put it into a class, but I can't get the array right.
Here's the version using the class:
class Ball {
float x;
float y;
float ySpeed;
float gravity;
int counter = 0;
Ball()
{
x = 300;
y = 300;
ySpeed = 2.5;
gravity = 0.2;
}
void move()
{
y = y + ySpeed;
ySpeed = ySpeed + gravity;
if (y > height-25 )
{ySpeed = ySpeed * -0.85;
y = height-25;
counter++;
}
println(counter);
if(counter >= 17)
{ySpeed=0;
y=height-25;}
}
void display()
{
ellipse(x,y,50,50);
}
}
//using the class:
Ball b1;
void settings()
{
size(800,600);
}
void setup()
{
b1 = new Ball();
}
void draw()
{
background(0);
b1.move();
b1.display();
}
Here's what I ended up with after messing it up completely.
//class Ball
class Ball {
float[] x;
float[] y;
float[] ySpeed;
float[] gravity;
int i;
int counter = 0;
//constructor
Ball()
{
x[i] = 300;
y[i] = 300;
ySpeed[i] = 2.5;
gravity[i] = 0.2;
}
void move()
{
y[i] = y[i] + ySpeed[i];
ySpeed[i] = ySpeed[i] + gravity[i];
//changes direction; (-25) to avoid movement beyong boundary
if (y[i] > height-25 )
{ySpeed[i] = ySpeed[i] * -0.85;
y[i] = height-25;
}
println(counter);
if(counter >= 17)
{ySpeed[i]=0;
y[i]=height-25;}
}
void display()
{
//draw ellipse
ellipse(x[i],y[i],50,50);
}
}
//using the class
final int i = 9;
Ball[] Balle = new Ball[10];
void settings()
{
size(800,600);
}
void setup()
{
Balle[i] = new Ball();
for (int i = 0; i < Balle.length; i++)
{Balle[i] = new Ball(x[i],y[i],50,50), i*4);
}
}
I suppose this looks weird because it's picked together from several different help pages... the current error is "variable x does not exist" on
{Balle[i] = new Ball(x[i],y[i],50,50), i*4);
I'm aware there are several other problems.
Right now I'm quite lost in figuring out how it works. Could somebody give me a hint?
variable x does not exist - It's because you don't have x as a global variable, but as a class variable, which is therefore only accessible from within the Ball class or by an instance of the Ball class. I don't exactly know why you're using arrays for x and y, primitives would do just fine. And don't forget to add the draw() method, as in processing, that serves as the 'main loop', it gets executed every 0.x sec (frameRate) so you MUST use that as well. Your other functions like display() etc.. can also be called from within the draw function.
Geez, what did I even do there?
Here it is:
Ball[] balls = new Ball[10];
void settings()
{
size(600,800);
}
void setup()
{
for (int i = 0; i < balls.length; i++)
{
balls[i] = new Ball();
}
}
void draw()
{ background(0);
for (int i = 0; i < balls.length; i++)
{
balls[i].move();
balls[i].display();
}
}
Is programming like that, stumbling around in the dark until you get hit by a brick...?
Here's a pseudo code.
If ball <= bottom, reverse the speed of ball.
(That means when it hits the floor, the speed reverses. Multiply it with -1)
Other wise, speedOfBall = speed - (gravity*time);
You can easily calculate the displacement in terms of coordinates as s = velocity*time + .5*gravity*time^2.
I want to make a group of array fade out until the last array object in this group was appended. And I use millis() to make every three object fadeout at a slower speed! So I create a function called boolean timelag(int time, int number)and each time I pass the time and sequence number into it and expect it will fadeout after 2 seconds after every third object was created, but seems that nothing happened
void draw() {
background(255, 255, 255);
for (int i=0; i<zoog.length; i++) {
zoog[i].jiggle();
zoog[i].display();
if(i%3 ==0 && i>=3){
time = millis();
timelag(time,i);
}
}
if(fadeout){
zoog[thatnumber].disappear();
zoog[thatnumber-1].disappear();
zoog[thatnumber-2].disappear();
}
}
My timelag function:
boolean timelag(int time, int number){
int thattime = time;
if(millis()-thattime>2000){
thatnumber = number;
fadeout = true;
}
else
fadeout = false;
return fadeout;
}
The whole code is here
Zoog[]zoog = new Zoog[1];
float count=0;
int xpos =0;
int ypos =0;
String message="haha";
int ntextsize = 20;
int nopacity =200;
int thistime = 0;
int thiscount = 0;
int time =0;
int number =0;
boolean fadeout = false;
int thatnumber=0;
//Zoog zoog;
void setup() {
size(400, 400);
xpos = int(random(width/2-200, width/2+40));
ypos = int(random(height/2, height/2-40));
zoog[0] = new Zoog(xpos, ypos, message, nopacity);
}
void draw() {
background(255, 255, 255);
for (int i=0; i<zoog.length; i++) {
zoog[i].jiggle();
zoog[i].display();
if(i%3 ==0 && i>=3){
time = millis();
timelag(time,i);
}
}
if(fadeout){
zoog[thatnumber].disappear();
zoog[thatnumber-1].disappear();
zoog[thatnumber-2].disappear();
}
}
void mousePressed() {
count = count + 1;
// int thiscount = 0;
if (count%3 ==0) {
xpos=int(random(30, width-30));
ypos=int(random(10, height-10));
}
else {
ypos = ypos+50;
}
nopacity = int(random(100, 255));
// text(message, xpos, ypos);
Zoog b = new Zoog(xpos, ypos, message, nopacity);
zoog =(Zoog[]) append(zoog, b);
}
boolean timelag(int time, int number){
int thattime = time;
if(millis()-thattime>2000){
thatnumber = number;
fadeout = true;
}
else
fadeout = false;
return fadeout;
}
class Zoog {
int x;
int y;
String thatmessage;
int opaci =0;
Zoog(int xpo, int ypo, String thismessage, int opa) {
x = xpo;
y = ypo;
thatmessage = thismessage;
opaci = opa;
}
void jiggle() {
x = x+int(random(-2, 2));
y = y+int(random(-2, 2));
}
void display() {
fill(0, opaci);
text(thatmessage, x, y);
print("x position is "+ x);
print("y position is "+y);
}
void disappear() {
for (int j=0; j<255; j++) {
opaci = opaci -j;
}
}
}
I assume that when you wrote...
if(fadeout) { ... }
you meant...
if(timelag()) { ... }
in your timelag function it's much more readable and faster(if even minutely) to just return true or false from the function rather than returning a variable, unless that variable is needed throughout your project over and over, which it doesn't seem like it is and if it is the function that changes it usually isn't needed to return a value unless you're checking the boolean of whether or not the change happened.
boolean timelag(int time, int number){
//int thattime = time; //You also don't need to create this you
//can simply use the time you're getting in the boolean statement
if(millis()-time>2000){
thatnumber = number;
return true;
}
else {
return false;
}
}
also, if you're trying to fix how long it takes for each zoog to fade out you need to give them all a number and then decrease that number each time the disappear function is called. Take the for loop out of the disappear and just have it subtract a unit from it each call in the draw loop.
void disappear() {
opacity -= somenumber //somenumber is usually something small and you can tweak it.
if (opacity == 0) {
dead = true;
}
}
You can think of the draw loop as your for loop. If you embed too many singular for loops it'll slow down the flow of your program. Right now, you probably don't even see them fading out and you probably don't get rid of them with the way the code is written right now.
And when you're testing it you can tweak that number until you find the sweet spot. If you want an amazing overview of all these concepts you can take a look here. Shiffman really goes deep into each aspect we're talking about here and it's short and fun to read.
First time i read the other post I misunderstood your goal. Anyway i've made a little tweak in your code that might help you understanding the way to go. BUT i did not moved it to an ArrayList, so this code below, kind of sucks... It can only, maybe, help you get things clear...
Zoog[]zoog = new Zoog[1];
float count=0;
int xpos =0;
int ypos =0;
String message="haha";
int ntextsize = 20;
int nopacity =200;
int thistime = 0;
int thiscount = 0;
//Zoog zoog;
void setup() {
size(400, 400);
xpos = int(random(width/2-200, width/2+40));
ypos = int(random(height/2, height/2-40));
zoog[0] = new Zoog(xpos, ypos, message, nopacity);
}
void draw() {
background(255);
for (int i=0; i<zoog.length; i++) {
zoog[i].jiggle();
zoog[i].display(); }
}
void mousePressed() {
count = count + 1;
// int thiscount = 0;
if (count%3 ==0) {
xpos=int(random(30, width-30));
ypos=int(random(10, height-10));
}
else {
ypos = ypos+50;
// thiscount = thiscount +1;
// thistime = millis();
// }
}
nopacity = int(random(100, 255));
text(message, xpos, ypos);
Zoog b = new Zoog(mouseX, mouseY, message, nopacity);
zoog = (Zoog[]) append(zoog, b);
zoog[zoog.length -2].disappear = true;
}
class Zoog {
int x;
int y;
String thatmessage;
boolean disappear;
int opaci =0;
Zoog(int xpo, int ypo, String thismessage, int opa) {
x = xpo;
y = ypo;
thatmessage = thismessage;
opaci = opa;
}
void jiggle() {
x = x+int(random(-2, 2));
y = y+int(random(-2, 2));
}
void display() {
if(disappear)
disappear();
fill(0, opaci);
text(thatmessage, x, y);
}
void disappear() {
opaci-=0.5;
}
}
I've made this code that successfully creates a 16x12 grid by 50x50 squares on a 800x600px board.
As you can see, the player moves to the coordinates of the players mouseclick.
Each square of the grid has an object of Felt (field) on it, which can be laast (locked). If a fields lock attribute is set to 1, the player should not be moved to that position.
How do i detect the field a player tries to move on to achieve this?
public class SimpleGame extends BasicGame{
private Image plane;
private float planeX;
private float planeY;
public SimpleGame()
{
super("SpilTest");
}
#Override
public void init(GameContainer gc) throws SlickException {
plane = new Image("figur.png");
}
#Override
public void update(GameContainer gc, int delta) throws SlickException {
Input input = gc.getInput();
if (input.isMousePressed(input.MOUSE_LEFT_BUTTON)) {
this.planeX = input.getMouseX() - 30;
this.planeY = input.getMouseY() - 50;
}
}
public void render(GameContainer gc, Graphics g) throws SlickException {
Felt board[][] = nytGrid();
int distancex = 0;
int distancey = 0;
int counter = 0;
for (int i=0; i < board.length ; i++) {
for (int j=0; j < board[i].length ; j++) {
if (board[i][j].getLaast() == 1) {
g.setColor(Color.red);
g.fillRect(distancex, distancey, 50, 50);
}
distancex += 50;
counter++;
if (counter == 16) {
distancey += 50;
distancex = 0;
counter = 0;
}
}
}
g.drawImage(plane, planeX, planeY);
}
public static void main(String[] args) throws SlickException {
AppGameContainer app = new AppGameContainer(new SimpleGame());
app.setDisplayMode(800, 600, false);
app.setTargetFrameRate(60);
app.start();
}
public Felt[][] nytGrid() {
Felt [][] board = new Felt[16][12];
for (int i=0; i < board.length ; i++) {
for (int j=0; j < board[i].length ; j++) {
int x = i;
int y = j;
board[i][j] = new Felt(x, y);
if (i == 5 && j == 5) {
board[i][j].setLaast(1);
}
}
}
return board;
}
}
First off, you should probably initialize the board in the init() method instead of render, so it doesn't have to do it every frame, and move the declaration for the grid next to the plane, planeX and planeY declarations in the class.
Now to disable movement into a locked square, first add a method to check if a square at certain coordinates is locked, so something along the lines of:
private boolean isLocked(int x, int y) {
int square = board[x/50][y/50];
if (square == 1) return true;
else return false;
}
Next modify the part of your update() method where you update the plane coordinates, so vaguely something like:
if (input.isMousePressed(input.MOUSE_LEFT_BUTTON)) {
int destX = input.getMouseX() - 30;
int destY = input.getMouseY() - 50;
if (!isLocked(destX, destY)) {
this.planeX = destX;
this.planeY = destY;
}
}
It's easy!
int mx = Mouse.getX();
int my = Mouse.getY();
But, it gives you the world cordinates, and you have to translate it to pixels:
int mx = Mouse.getX();
int my = Mouse.getY() * -1 + (Window.WIDTH / 2) + 71;