I am making a simple sequence from randomly generated numbers. Each number will show an image linked to it.
for example,
the value 1 will show a picture of a cat.
value 2 a dog
and value 3 a mouse.
Each image has it's own dedicated imageview, the layout looks like this by default, i.e image views that store black until it's number is called:
Each time the sequence increments. so on the second run two images will show, on the third 3 will show and so on.
The problem I am having is that all the images show at once. So for sequence one just the one image flashes (which is what I want). but on the second run both images show at once together instead of showing the first image then the second.
So to clarify let's say on the four runs the stored array is 1,2,3,3 I would want
image 1 to show, and disappear.then
image 2 show and disappear. then
image 3 show and disappear
and then image 3 to show and disappear.
But what I actually get is on the fourth run 1,2&3 will show at once and disappear at the same time together. How can I break this up to achieve what I want. I have tried many methods and the same result happens. I can't get my head around this problem.
Here is my code:
ArrayList<Integer> stored_vals = new ArrayList<Integer>();
public void Gen() {
int i=0 ;
Random rand = new Random();
int rndInt = rand.nextInt(3)+ 1 ;
list.add(rndInt);
int totalElements = list.size();
Log.d("LOOK", Integer.toString(rndInt));
Log.i("VALUE LIST ", list.toString()+" <<<<LIST HERE");
while(i < totalElements) {
retval =list.get(i);
Log.d("RETVAL", Integer.toString(retval));
String imgName = "flash" + retval;
int id = getResources().getIdentifier(imgName, "drawable", getPackageName());
if (retval==1){
Cat.setImageResource(id);
Reset_View();
}
else if (retval==2){
Dog.setImageResource(id);
Reset_View();
}
else if (retval==3){
Mouse.setImageResource(id);
Reset_View();
}
i++;
}
}
To try and delay the images showing at one at a time and to reset to it's default after showing for a few seconds I call Reset_View(); which is the following code:
CountDownTimer Reset_View = new CountDownTimer(1000 , 0010){
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
Centre.setImageResource(R.drawable.i1);
upperRight.setImageResource(R.drawable.i2);
lowerRight.setImageResource(R.drawable.i3);
lowerLeft.setImageResource(R.drawable.i4);
upperLeft.setImageResource(R.drawable.i5);
}
};
So how can I achieve what I want. I have been stuck on this idea for weeks.
This is a high level idea of what you could do.
Put all the showing and hiding in the countdowntimer. So basically you would need to handle the 'onTick' and hide or show the images when needed. Something like 'time > 0 and < 1000' hide all but the first image. 1000 to 2000, show only second image. 2000 to 3000, show only third image. On finish, hide all.
When you instantiate the timer after the for loop, if retval is 1 - then 1000 would be how long to run, retval = 2, then 2000, retval = 3, then 3000.
There is probably a better way to do it but this is the first thing that comes to my mind.
One problem might be that Reset_View(); is not a method. The line even states public CLASS Reset_View(); extends CountDownTimer. ( I don't know ho that can be a valid class name but whatever) Therefore, calling Reset_View(); will not actually do anything.
You need to change the name of the class to something else, I suggest ResetTimer. Then to reset the Views you must create an instance of ResetTimer and use its start() method like this:
new ResetTimer(1000, 1000).start();
Note: the first number in the constructor is the total time (in milliseconds) until the timers onFinish() is called. The second one it the time between the onTick()s. Since you don't use this method, the number you put in there doesn't matter.
Related
I have a problem since yesterday.
I'v created a jTable with the WindowBuilder in Eclipse and currently are trying to get the number of the selected row, by using the .getSelectedRow() function, but it is always returning -1 (no row selected), even when I have selected something.
This is my current code for testing the output:
public void checkActiveItem() {
System.out.println(tableBills.getSelectedRow());
}
I try to let it run this way trough a timer and at least that seems working:
Timer time = new Timer();
time.schedule(new TimerTask() {
public void run() {
Frontend f = new Frontend();
f.checkActiveBill();
f.checkActiveItem();
}
}, 250, 250 );
The table currently has just one entry, but even the first row dosn't get returned on selection.
I can create new rows by clicking add (and name them by entering a name in the textfield next to the add button before)
To create a new row I use this code, maybe there is the problem?
public void addBill() {
//maybe need this value somewhere else to, so let -1 and +1 as it is
int numbersOfBills = tableBills.getRowCount() - 1;
Bill newBill = new Bill(txtBillName.getText(), numbersOfBills + 1);
DefaultTableModel billModel2 = (DefaultTableModel) tableBills.getModel();
int billNb = numbersOfBills + 1;
billModel2.addRow(new Object[] {newBill.getBillNr(),newBill.getBillName(), newBill.getItemsInBill()});
}
The reason why you are getting -1 from getSelectedRow() even though you seem to have "added a row" is, because the Frontend object you are calling checkActiveItem() on is a completely different Frontend object than the one you are seeing.
The issue is here, inside of your Timers run():
Frontend f = new Frontend();
You create a new Frontend object for each timer iteration. And you call checkActiveItem() on exactly this object, not on the frontend you are seeing and pressing buttons on. Hence, the incorrect output.
As a solution, don't create new Frontends, instead, call checkActiveItem() on your original frontend object, which you made visible.
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.
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();
I'm trying to create random items in a libgdx project.I'm relatively new to Java,but here is the code I've come up with for the method.
I've been at this for a week now,and figured I'd ask here for an answer.
I've been trying to come up with something that works first.So please do forgive the shabby code.
The number parameter of the method is the number of items that will be created.
The item just needs to have a random x positon,which is generated within the constraints of the width of the container.
The game is as bottom up scroller,with different platforms being generated.
private Item[] generateRandomItems(int number){
Money[] items=new Money[number];
for(int i=0;i<number;i++){
Random r=new Random();
int x =r.nextInt(120)+3;//136 is the width of the container to which the item is to be generated
Money tempitem=generateMoney(x);//generateMoney() just returns a new instance of the Money class with the created x passed in as a param.
if(i!=0) {
for (int j=0;j<i;j++) {
boolean failed=true;
while (failed) {
//getItem() returns the bounding rectangle/circle f the item
if (!Intersector.overlaps(tempitem.getItem(), items[j].getItem())) {
failed = false;
items[i] = tempitem;
}else{
Random random= new Random();
int newX=random.nextInt(120)+3;
tempitem=generateMoney(newX);
}
}
}
}else{
items[i]=tempitem;
}
}
return items;
}
I don't know if this is a correct way to do it or not,but the created Items do collide sometimes.I've been trying to find what's wrong with the code for sometime now.Any suggestions to improve the code are also appreciated.
Edit::I Know that the code is unnecessarily complicated.This is my first attempt at procedural generation.So please do forgive me.
Instead of generating a new random position if there is a collision, you should move it deliberately left or right until there is no collision. To illustrate the problem reusing random generation after each collision, if you have 10 slots and 9 slots are already filled, it could take a long time to find that open slot using random generation as you would be almost certain to hit the same object numerous times. However, if you keep track of where you’ve checked and deliberately move to a new location each time, then the worst case scenario is you’d hit each object one time before finding the empty slot.
You can check how much of an overlap there is and move the object by that amount to clear the object, then check to make sure it didn’t collide with another object next to it, if it did then keep moving it over until there is a free spot. If you hit the edge of the screen, move to the opposite side and keep moving until you find a free spot.
Also, as good coding practice you should avoid hard coding numbers (like 120+3) into method calls. Since you use the same value in multiple places, if you decide to change the width of your container to 500, then you have to change it in all those places...and if you forget to change one you’re opening yourself up for a nightmare of bug hunting. Instead you can either set an integer such as containerWidth=120 or set the container width directly using container.setWidth(120) and then use container.getWidth() each time you call your random method to get the width of the container the random value is being constrained too. Either way will work fine, whichever is better for your workflow. And I know you said this was quick and sloppy code just to get it going, so you may already be aware of this.
Thanks for the answers.I now know that checking each generated item for collision without saving the previously generated item is bad.
But I got the previous code working after some help,and wanted to share it with anyone who would need it in the future.
I moved the checking part into a new method,and added a new flag to see if the item was generated correctly,after checking for collision from all the items before it.
private Item[] generateRandomItems(int number){
Money[] items=new Money[number];
for(int i=0;i<number;i++){
Random r=new Random();
int x =r.nextInt(120)+3;
Money tempitem=generateMoney(x);
if(i>0) {
boolean generated=false;
while (!generated) {
boolean f = checkIfItemOverlapsWithPrevious(items, tempitem);
if (!f) {
items[i] = tempitem;
generated = true;
} else {
Random random = new Random();
int newX = random.nextInt(120) + 3;
System.out.println("Collided");
tempitem = generateMoney(newX);
}
}
}else{
items[i]=tempitem;
}
}
return items;
}
private boolean checkIfItemOverlapsWithPrevious(Money[] items, Money tempitem) {
for(Money item :items){
if(item!=null) {
if (Intersector.overlaps(tempitem.getItem(), item.getItem())) {
return true;
}
}
}
return false;
}
This post is related to my last post.The block of code changes the text to desired color after desired time.
however, now I want to change the color of a perticular word such that each letter gets the equal time.EG if "hello" have been given a time of 1000 milliseconds (have 5 letters) then 'h''e''l''l''o' each letter should get 1000/5 milliseconds i.e 200 milliseconds each.
I implemented swing timer for this :
public Reminder() {
a[0]=2000;
a[1]=1000;
a[2]=3000;
a[3]=5000;
a[4]=3000;
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
point =point +arr[i].length();
i++;
doc.setCharacterAttributes(0,point+1, textpane.getStyle("Red"), true);
timer.setDelay(a[i]);
}
};
timer = new Timer(a[i], actionListener);
timer.setInitialDelay(0);
timer.start();
For this to happen, shoud I use another Timer inside the actionListener to give further timings to a perticular letter?Or should I first break the time by .length()
and then use the timer?I cannot decide a better way.Any ideas?
You should never need more than one timer. Since you know ahead of time exactly when everything should happen, just calculate those times, put them in a list (sorted by time) and execute each one.
public colorize(int offset, int length) {
long triggerTime[] = new long[length];
long startTime = System.currentTimeMillis();
for (int i=0; i<length; i++) {
triggerTime[i] = startTime + (1000*i)/length;
}
for (int i=0; i<length; i++) {
//just wait for the next time to occur
Thread.sleep(triggerTime[i]-System.currentTimeMillis());
doc.setCharacterAttributes(offset, i+1, textpane.getStyle("Red"), true);
}
}
This may strike you as very pedestrian because it does not use a TimerTask object, but it is effective, efficient, and easy to debug. You simplty call this method on whatever thread you want, and it occupies the entire thread, and the word will be colorized at a rate such it is completed in 1 second.
You could, if you don't have a thread handy, make a timer that calls this, but the only reason for that is to access a thread. The real point is: don't set up multiple timers, just make an array of time values. After one event is satisfied, set to delay until the next time. You never need multiple timers.
It would be a little cleaner if you made an object that represented the coloring of a character (or whatever action you want) and you put together a collection of these actions. Then sort the entire collection by time they are to go off. The loop above would walk through the collection, waiting until the time for the action arrives, and then executing it. Another advantage of this approach is that you could clear the collection and that would terminate the loop.
See the discussion of the overuse of timers on my website to understand why this is bad.