Processing 2: Random text from array to appear on click? - java

The movie quotes are just appearing randomly in quick succession rather than the desired effect of it pulling one random movie quote from the text document.
Ideally I want a new quote to appear by the click of the mouse.
Tried to make the array and index a global variable but then the text wouldn't display for some reason.
PImage wallpaper;
void setup() {
size(600, 600);
wallpaper = loadImage("Theatrescreen.png");
}
void draw() {
background(wallpaper);
String[] moviequotes = loadStrings("moviequotes.txt");
int index = int(random(moviequotes.length));
text(moviequotes[index], mouseX, mouseY);
}
void mousePressed() {
}

Code within draw() is executed in an infinite loop. I think that is your problem. See Processing Reference - draw(). To take care of the problem, consider using noloop(). See Processing Reference - noloop().

Your implementation of Random isn't correct. Try something like this:
void draw() {
background(wallpaper);
String[] moviequotes = loadStrings("moviequotes.txt");
Random randIndex = new Random();
int index = randIndex.nextInt(moviequotes.length); // generate a random index from 0 to movieqoutes.length
text(moviequotes[index], mouseX, mouseY);
}

You are generating a new random movie quote each draw cycle. That means a lot (more than 25 dependeing on framerate) each second.
You can set the framerate like this:
void setup() {
frameRate(1);
}
or add a counter to your draw loop, so that you generate a new quote only once in a while

Related

How do I detect the collision between the bullet and the enemy? [duplicate]

This question already has answers here:
Ball to Ball Collision - Detection and Handling
(15 answers)
Closed last year.
I'm creating a shooter game and im unsure on how to make it detect the fact that the bullet has hit the enemy. This is the boolean that was given
boolean isShot(Bullet bullet) //is shot sequence
{
if (bullet!=null)
{
if (abs(this.x - bullet.x) < 20 &&
abs(this.y - bullet.y) < 20)
return true;
}
return false;
}
and this is the part where i try make it detect the collision and make the enemy disappear but it keeps giving me errors no matter what i try.
import java.util.ArrayList;
int score;
Player p1;
Enemy[] e= new Enemy[4];
ArrayList<Bullet> bullet = new ArrayList<Bullet>();
void setup()
{
size (1000, 1000);
p1= new Player(500,5, 40);
e[1]= new Enemy(100,1000,3);
e[2]= new Enemy(500,800,3);
e[3]= new Enemy(700,700,3);
// b1= new Bullet(500,500,-5);
}
void draw()
{
background(255);
p1.render();
e[1].render();
e[1].move();
e[2].render();
e[2].move();
e[3].render();
e[3].move();
text("Score:" + score,50,50);
for (Bullet b: bullet)
{
b.render();
b.move();
}
if (e[1].isShot(Bullet))
{
e[1]=null;
}
Its at the bottom of this peice of code. When i try put bullet in lowercase it says "the function isShot() expects paramaters like "isShot(Bullet)" but when i capitalise the B in bullet it tells me that bullet isnt a variable.
"bullet" with lowercase b is an array of Bullets, but isShot() expects a single Bullet object. And "Bullet" with capital B is not a variable, but a class (I suppose).
So, you either need to create another object of Bullet or use one of the Bullet object in your "bullet" ArrayList.
You are almost there.
I suggest you use more meaningful names for your parameters.
First of all, you have to populate the ArrayList bullet in your setup() or elsewhere you want in your code.
After this, if you want to check that condition using isShot function you should pass to it an instance of an Object, not the class Object itself.
This can be easily achieved by including the function in your for loop.
While it is always good to practice, I suggest you to first understand the basics of the language and then move to more complex examples (custom classes, arrays iterations and so on).
void setup()
{
size (1000, 1000);
p1= new Player(500,5, 40);
e[1]= new Enemy(100,1000,3);
e[2]= new Enemy(500,800,3);
e[3]= new Enemy(700,700,3);
bullet.add(new Bullet(500,500,-5)); // e.g. to populate array
}
void draw()
{
background(255);
p1.render();
e[1].render();
e[1].move();
e[2].render();
e[2].move();
e[3].render();
e[3].move();
text("Score:" + score,50,50);
for (Bullet b: bullet)
{
b.render();
b.move();
if (e[1].isShot(b)) // now you can use b which is an instance of Bullet
{
e[1]=null;
}
}

JAVA / Processing - Instantiating multiple of same objects - Only displays one out of 5

I have a problem regarding drawing multiple of the same objects. They end on top of each other, and their "Object values" even get added together e.g. if a zombie has "2" movement value and there is added 2 into the current level. Then when zombies are moved, they move "4" each. This does not happen if two different objects are moved e.g. Zombie and Dragon. I have created the following code based on my project - for a simpler overview. However, the behavior is the same.
It should be mentioned the objects of the same type have the same "HashCode". I have also made comments and println to help figure out the problem. Each of the 5 objects have different position (When set). However, they are rendered on top of each other and merged (Movement).
EnemyDatabase enemyDatabase;
ArrayList<Enemy> enemiesInlevel = new ArrayList<Enemy>();
void setup()
{
size(600, 600);
enemyDatabase = new EnemyDatabase();
enemyDatabase.enemies.add(new Enemy("Zombie", 3));
//If dragon is added - Then it can draw both - But only once
//enemyDatabase.enemies.add(new Enemy("Dragon", 10));
//Add 10 zombies to the level
for(int i=0; i< 5;i++)
{
//5 Zombies are created and succesfully added to the database
enemiesInlevel.add(enemyDatabase.enemies.get((int)random(0, enemyDatabase.enemies.size())));;
}
for(int i=0; i<enemiesInlevel.size();i++)
{
//Sets the position of all 5 - Gives random position
Enemy enemy = enemiesInlevel.get(i);
enemy.SetPosition();
}
}
void draw()
{
background(255, 200, 0);
//Draw 5 enemies - Of index 0 (Zombie)
for(int i=0; i<enemiesInlevel.size();i++)
{
Enemy tempEnemy = enemiesInlevel.get(i);
tempEnemy.draw();
//It runs 5 times - print returns 5 total objects in enemiesInlevel
}
}
class EnemyDatabase
{
ArrayList<Enemy> enemies = new ArrayList<Enemy>();
}
class Enemy
{
String enemyName;
int enemyHealth;
PVector enemyPosition;
public Enemy(String name, int hp)
{
enemyName = name;
enemyHealth = hp;
}
public void SetPosition()
{
enemyPosition = new PVector(random(0, width), random(0, height));
//Each of the objects has a random position
println(enemyPosition);
}
public void draw()
{
rect(enemyPosition.x, enemyPosition.y, 25, 25);
}
}
UPDATE
Here is an image of the problem
As the image shows from the output in the image line: The enemies have different positions when added to the array (5 different enemies) However, as the image shows, it still only displays one - And this happens because all of the sudden the positions is the same. I even tried to give a "Random position" in the "DrawImage" all of the enemies still end up having the same position
Hope you guys can figure it out. I certainly have a hard time - I usually don't work in processing Thank you
DrSatan's comment is correct. You're only ever adding a single Enemy to your EnemiesDatabase. So when you select 5 random enemies, you're really just selecting the same enemy 5 times.
It might look like they have different positions in your print statements, but that's because you're printing out the position every time you set it. You're setting it five times, but only the last position really counts for anything.
In other words, you're taking a single instance of Enemy, moving it around the screen 5 times, and printing out the position each time. But then when you draw it, only the last position you moved it to is what you see.
You need to refactor your code so you add more enemies to your EnemyDatabase, but please note that you're going to have similar problems no matter how many enemies are in your EnemyDatabsae, because you don't have any logic that makes sure you don't select the same instance twice. Even if you had 100 enemies in your database, nothing is stopping your random function from selecting the same enemy 5 times.
If I were you, I'd rethink my design. I don't really see the reason to have a separate EnemyDatabase class at all. Maybe just create a function that adds X random enemies to the level, where X is a parameter? That's up to you, but your fundamental problem here is that you only have a single instance of Enemy.

Using a CountDownTimer and Queue together

I am working on a "Simon Says" pattern game. The player must repeat an increasingly long pattern till they mess up.
The game consists of a 2x2 grid of colors, each with a darker one behind it. By changing the alpha from 1--->0---->1. I give the effect of clicking.
Below is the code I am using to display the pattern as it increases, it's called whenever the pattern resets or increases. But currently it always skips the last value in the pattern, and if the same color is repeated it does not flash again, it simply remains dark, what am I doing wrong?
Helpful Information:
Pattern is the arraylist where I am storing the pattern the user must repeat.
getColorById returns the corresponding ImageView for each color [0-3]
TLDR:
I need to flash every single item in an arrayList called pattern, so the player can see it and repeat it, yet currently it skips the last item and if the same item is repeated it simply stays flashed versus flashing twice.
EDIT: Sometimes, the last item in the sequence does show, but it is very random on whether it shows or not.
public void flashPattern(View view){
final Queue<Integer> queue = new LinkedList<>(pattern);
final int timeBetweenSteps = 500;
new CountDownTimer(pattern.size() * timeBetweenSteps, timeBetweenSteps) {
private ImageView lastLight = null;
#Override
public void onTick(long millisUntilFinished) {
if (lastLight != null) {
lastLight.animate().alpha(1f).setDuration(250);
}
lastLight = getColorById(queue.remove());
lastLight.animate().alpha(0f).setDuration(250);
}
#Override
public void onFinish() {
if (lastLight != null) {
lastLight.animate().alpha(1f).setDuration(250);
}
}
}.start();
}

How do I change alpha of an image view multiple times using thread.sleep?

I am trying to create an animation for my game. I am trying to make an animation of a coin flip that will stop under certain conditions.
So far I have tried to change an image view multiple times within one method and using thread.sleep to delay the transition between the pictures.
Using 12 different images I am now trying to make it so the alpha of the first image will set to 0 and the second image will set to one, the the second image will set to 0 and the third will set to 1, etc...
The way I am currently trying to do it is by putting images inside of an array of ImageViews and then calling them sequentially.
setContentView(R.layout.coin_flip_screen);
for(int i = 0; i < 4; i++){
headsTails[i].animate().alpha(0).setDuration(100);
headsTails[i+1].animate().alpha(1).setDuration(100);
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
final int size = imageView.length;
final int animTime = 300;
final Handler animationHandler = new Handler();
Runnable animationRunnable = new Runnable() {
int i = 0;
#Override
public void run() {
if(i == size-1){
animationHandler.removeCallbacks(this);
return;
}
imageView[i++].animate().alpha(0f).setDuration(animTime).start();
imageView[i].animate().alpha(1f).setDuration(animTime).start();
animationHandler.postDelayed(this, animTime);
}
};
animationHandler.post(animationRunnable);
This code will iterate through all your imageviews in the array and stop itself once all the images are consumed.
Play along with your animTime variable until you get the perfect animation effect. Ideally it should be around 300 to 500 ms.
I will personally not use array of imageviews to create this effect as
it will eat up the memory. There are many more efficient ways to do
the coin flip animation, which you can google when you get time.
This should fix it
headsTails[i].animate().alpha(0).setDuration(100).start();

Programming Video Games for the Evil Genius:Project 10:Radical Racing-The Cars

Iv'e looked all over for answers to this book. And I know anyone else who has tried to read this book feels the same way. It's called "Programming Video Games for The Evil Genius" Is there anyone who has read this book? I'm on project 10:Radical Racing-The Cars. Everything compiles correctly but for some reason my cars are not showing up in the correct spot on the JFrame. They should be showing up under the two white lines. I'm positive the code is exactly the same as in the book, but the book is wrong. I have already tried changing the HEIGHT part of the point of origin but no matter what I do it does not budge. I can't attach an image because I don't have a rep of at least 10 .This is the code that the deals with the placement of the cars.
public class TheCars extends JFrame
{
final int WIDTH = 900; int HEIGHT = 650;
double p1Speed = .5, p2Speed = .5;
Rectangle p1 = new Rectangle(WIDTH/9,HEIGHT/2, WIDTH/30,WIDTH/30);
Rectangle p2 = new Rectangle(((WIDTH/9)+((int)((WIDTH/9)*1.5)/2)),(HEIGHT/2)+
(HEIGHT/10),WIDTH/30,WIDTH/30);
//the constructor
public TheCars()
{
//the following code creates the JFrame
super("Radical Racing");
setSize(WIDTH,HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
//start the inner class (which works on it's own because it is a thread)
Move1 m1 = new Move1();
Move2 m2 = new Move2();
m1.start();
m2.start();
}
//this will draw the cars and the racetrack
public void paint(Graphics g)
{
super.paint(g);
//set the color to blue for p1
g.setColor(Color.BLUE);
//now draw the actual player
g.fill3DRect(p1.x,p1.width,p1.width,p1.height,true);
//set the color to red for p2
g.setColor(Color.red);
//now draw the actual player
g.fill3DRect(p2.x,p2.width,p2.width,p2.height,true);
}
private class Move1 extends Thread
{
public void run()
//This should all be in an infinite loop so that the process repeats.
{
while(true)
{
//now put in the try block. This will let
//the program exit if there is an error
try
{
//first refresh the screen
repaint();
//increase speed a bit
if(p1Speed<=5)
p1Speed+=.2;
p1.y-=p1Speed;
//this delays the refresh rate
Thread.sleep(75);
}
catch(Exception e)
{
//if there is an exception (an error), exit the loop
break;
}
}
}
}
private class Move2 extends Thread
{
public void run()
{
//this should all be in an infinite loop so the process repeats
while(true)
{
//now put the code in a "try" block.
//this will let the program exit if there is an error
try
{
//first refresh the screen
repaint();
//increase the speed a bit
if(p2Speed<=5)
p2Speed+=.2;
p2.y-=p2Speed;
//this delays the refresh rate
Thread.sleep(75);
}
catch(Exception e)
{
//if there is an exception (an error), exitthe loop
break;
}
}
}
}
public static void main(String[]args)
{
new TheCars();
}
}
Assuming you're painting those Rectangle objects directly onto the screen, we have to assume that the expressions "HEIGHT/2" and "HEIGHT/2 + HEIGHT/10" are coming out equal, and nonzero but small. That would be the case if HEIGHT is an int, and the value is more than 2 and less than 10. Presumably the value would need to be a couple hundred, at least, for those boxes to show up in the middle of the screen. Check the value of HEIGHT (just using a System.out.println() would be fine) and make sure it's the actual height of the window.
EDIT
Now that we see the rest of the code: the second argument to each call to fill3DRect() is wrong. It should be the y member of the Rectangle objects, which is a large, varying number, but you're passing the width member, which is a small fixed number. Change both the calls to look like this and you'll be back on track:
g.fill3DRect(p1.x, p1.y, p1.width, p1.height, true);

Categories

Resources