Its not really an animation, but I want it so i have a flashing underscore next to my text. I want this to simulate that more text can be entered..
e.g. one second its '_' and the other second its gone..
Thanks :D
ps I tried an idea where i had a while(flashing) loop and in there i made a string equal '_' and then made it equal '' but that didnt work..
while(flashing) {
s = "_";
s = "";
}
Thanks for the help in advance!
EDIT:::
This is how i am displaying the string in the game:
drawCenteredString(fontRenderer, "Missile Command Center" + s, width / 2, 40, 0xffffff);
Like #Vulcan said, you actually can't do this with a while loop. You have to 'redraw' the centeredString every second or so, once with an underscore and next time without the underscore
You didn't tell us what kind of graphic libraries you are using.
If you want to do something like a flashing underscore there are two ways, one can be very bad, the second can be better.
The first one is something just like (pseudocoded):
while(flashing){
textView.setText(textView.getText()+"_"); // I am assuming that you are using a text view, take this as pseudocode, you can do to whatever you want.
sleep(500); //that is half a second
textView.setText(textView.getText().substr(0,textView.getText().length()-1));
sleep(500);
}
The second is better.
I assume you are using something like OpenGL to draw the graphics (as minecraft do, if I remember well).
private long timePassed = 0;
public void draw(long delta){
timePassed += delta;
String t = textView.getText();
if(timepassed > blinkingSpeed){
timepassed = 0;
if("_".equals(t.substr(t.length()-1,t.length()))){
//The last char is the underscore, i remove it.
textView.setText(t.substr(0,t.length()-1));
}else{
//The last char isn't an underscore. I add it.
textView.setText(t + "_");
}
}
delta is a difference between the last time we done a loop and the actual time.
so when calling draw method you should have something like this
//metod where draw is called
delta = Sys.getTimer() - lastTimerGotten;
lastTimerGotten = Sys.getTimer();
draw(delta);
//etc etc
Obviously each frame rendering you should call the draw(long delta) method.
I hope you understand what I am trying to explain you.
There is no way to make what you first wrote work.
Related
I'm trying to use JFugue 5.0.9 in my Java project to create *.midi files with it. While implementing JFugue's midi capabilities into my project that uses frequencies of a 24 tune makam piano, I realized it has some tune issues.
For example this code:
ChordProgression cp = new ChordProgression("I-III-IV-iv").setKey("E");
System.out.println(cp);
Player player = new Player();
player.play(cp);
should print
E4MAJ G#4MAJ A4MAJ A4MIN
on console as it's said here.
But prints
E4MAJ E4MAJ E4MAJ A4MIN
in my project. Yes, first three chords are same for some reason. They sound same also, of course.
Also, while using microtones like "m390", it doesn't sound exactly in that frequency.
In another file, in the main method I wrote this:
Player player = new Player();
player.play("A4 m440 m400 m390 m380 m370 m360");
I know that A4 and m440 are the same but as it's said here, A5 and m440 should sound same. But in my project A4 and m440 sound same but it's not exactly 440Hz. When I realized something goes wrong, I decided to use a tuning app and here are the frequencies it calculated respectively:
221.5 221.5 197.5 186.6 186.6 186.6 176.2
As you can see, it plays something very near A3 instead of a clear A4. But this is not all. It also sounds exactly same for m390, m380 and m370.
What exactly is wrong here? Any help would be appreciated.
A little note: I'm pretty sure it has nothing to do with my project. I tryed running the codes above in a brand new project, the same problems occured. And there's no problem with my system because my main project and any other softwares like SunVox, they all sound very good actually.
OK, I had a look at the source codes of JFugue 5.0.9 and here is what I got in ChordProgression.java:
/**
* Only converts Roman numerals I through VII, because that's all we need in music theory...
* VIII would be the octave and equal I!
*/
private int romanNumeralToIndex(String romanNumeral) {
String s = romanNumeral.toLowerCase();
if (s.startsWith("vii")) { return 6; }
else if (s.startsWith("vi")) { return 5; }
else if (s.startsWith("v")) { return 4; }
else if (s.startsWith("iv")) { return 3; }
else if (s.startsWith("iii")) { return 2; }
else if (s.startsWith("ii")) { return 1; }
else if (s.startsWith("i")) { return 0; }
else { return 0; }
}
A little laziness... :D One of the problems lies right here. If you use toLowerCase() method without specifying a locale, it causes some problems in runtime. In Turkish alphabet which I'm using right now lower case of I is "ı", not "i". So, the program converts my chords from "I-II-III" to "i-i-i" because as you can see there is no if statement for lower case I of Turkish alphabet (ı) and this leads it to return 0 as in the case of "i".
To solve this issue, we have to either delete lower case conversion and write all if statements for also upper case I's or set default locale to "en" to make sure it converts (upper case)I's to (lower case)i's. So, this should be used in the source:
Locale.setDefault(new Locale("en"));
Fortunately, JFugue is an open source software published under Apache 2.0.
This still doesn't explain why tunes sound wrong but now at least we know that these are totally different problems. Or maybe it seems so... I don't know. I will edit this answer if I ever find out an explanation or a solution for the rest.
Edit
Finally I figured out the problem with microtones by accident. I decided to look at microtone calculation functions in the source one more time.
In MicrotonePreprocessor class (which is in org.staccato package) there is a function named convertFrequencyToStaccato(). What this function does is convert frequency to midi note number and pitch bend value. At the 107th line, that code rounds semitone, octave and pitch values if calculated pitch value is very close to the next note:
// If we're close enough to the next note, just use the next note.
if (pitches >= 16380)
{
pitches = 0;
semitone += 1;
if (semitone == 12)
{
octave += 1;
semitone = 0;
}
}
The line where pitch is reset should be changed as:
pitches = 8192;
Because, you know, neutral pitch value is 8192. 0 (zero) is minimum pitch value and 16384 is maximum pitch value. At first, I thought the same way as the developer: "After 16384, it should be 0. That is okay. No problem here.". Then I said "What if I change pitch-reset value from 0 to 8192?". It worked. This was a beautiful perception error we both had. :D I'm really having a lot of laugh now.
This fixes the microtone issue. I can hear perfect intervals now! I feel happy and satisfied.
Edit2
I just wanted to share my further changes which results in better microtonal tunning:
if (pitches >= 12288)
{
int diff = 16384-pitches;
int applieddiff = 8192-diff;
pitches = applieddiff;
semitone += 1;
if (semitone == 12)
{
octave += 1;
semitone = 0;
}
}
This also helps use semitone (black) keys on a midi-board instead of only tone (white) keys with high pitch values. So, if you send the data to another software, it will detect all keys seperately. For example, there were no G and G# before, only G and G-with-high-pitch. These caused keys to stop eachother when note-on messages are sent simultaneously.
I am currently trying to figure something out. For my world editor I want my program to read a text file and use its content as code material. I've already made a decent file reader but now I've got a problem. In the console I am getting the right output, the file has only one line that says:
this.makeGrass(new Vector3f(0, 1, 2));
this is actually part of a code that tells my program to render a specific object to the scene, in this case it's a grass model. However instead of just printing this information to the console with
System.out.println(aryLines[i]);
I want to be able to use the information stored on the .txt file so I can actually add it to my rendering code. The entire method that prints the lines on the text file to the console is:
public void TextOutput()
{
String file_name = "C:/Text.txt";
try
{
StoreCoords file = new StoreCoords(file_name);
String[] aryLines = file.OpenFile();
int i;
for (i = 0; i < aryLines.length; i++)
{
System.out.println(aryLines[i]);
// !! How to use the information as part of my code ??
}
} catch(IOException e)
{
System.out.println(e.getMessage());
}
}
I hope you understand what I want: The content of my text file is a piece of code that I want to use further instead of having it just print to the console, I'm sure this is possible but I wouldn' know how.
As Java is a compiled language, you'd have to recompile at runtime and I am not sure that is even possible. If I were you, I'd hardcode in my own commands. You want to call a function called makeGrass, hardcode it in. Maybe in your text file you can have this:
makeGrass:0,1,2
Then have this right after the println:
if(aryLines[i].startsWith("makeGrass:")) {
String Arguments = aryLines[i].substring(aryLines[i].indexOf(":")+1, aryLines[i].length());
ArgArray = Arguments.split(",");
this.makeGrass(new Vector3f(Double.parseDouble(ArgArray[0]), Double.parseDouble(ArgArray[1]), Double.parseDouble(ArgArray[2])));
}
I'm going to leave my answer like this, assuming you are an experienced programmer. If I am wrong feel free to ask and I will explain it to you. I can also explain how to modify it to add different commands if you want.
Also, this is rather unsafe because if the input is in the wrong format it will crash the app. If you plan on letting users edit the file, then I can show you how to add on safeties.
Hope this helped,
Joseph Meadows
Okay, thanks to Joseph Meadows for the hint, I'm doing the following thing, right after the println statement I've added the code provided by him. To make ArgArray work I had to put String[] before it and also I had to create a new constructor in my Vector3f class to match the Double.parseDouble thingy..
public void TextOutput()
{
String file_name = "C:/Users/Server/Desktop/textText.txt";
try
{
StoreCoords file = new StoreCoords(file_name);
String[] aryLines = file.OpenFile();
int i;
for (i = 0; i < aryLines.length; i++)
{
System.out.println(aryLines[i]);
if(aryLines[i].startsWith("makeGrass:")) {
String Arguments = aryLines[i].substring(aryLines[i].indexOf(":")+1, aryLines[i].length());
String[] ArgArray = Arguments.split(",");
this.makeGrass(new Vector3f(Double.parseDouble(ArgArray[0]),
Double.parseDouble(ArgArray[1]),
Double.parseDouble(ArgArray[2])));
}
}
} catch(IOException e)
{
System.out.println(e.getMessage());
}
}
my original Vector3f constructor is:
public Vector3f(float x, float y, float z)
{
this.m_x = x;
this.m_y = y;
this.m_z = z;
}
and to make the code in the TextOutput method work I've added another constructor right below the original one..
public Vector3f(double parseDouble, double parseDouble2, double parseDouble3) {
this.m_x = (float) parseDouble;
this.m_y = (float) parseDouble2;
this.m_z = (float) parseDouble3;
}
Now everything works great, the console gives me the apropriate statement
makeGrass:0,1,2
and the rendering system creates the grass model at the apropriate coordinates, the only thing I want to change now is that I don't have to add an additional constructor to the Vector3f class, I'm sure I'll figure that out too.
In the picture provided in this link you can see exactly what's going on:
http://www.pic-upload.de/view-27720774/makeGrassEx.png.html
As you can see, the content of the text file is printed out in the console (the numbers below is the fps counter) and the coordinates provided by the text file are interpreted correctly, two grass models being displayed at the respective coordinates which is exactly what I wanted!
Thanks again for your help Joseph Meadows, this is exactly what I was looking for!
I am not sure if you solved this yet, but you did not need the second constructor. I was unsure of the data type you were using for the coordinates, and I assumed you use doubles because that is what I have grown accustomed to using.
In actuality, all types can be parsed from a string. Look here:
this.makeGrass(new Vector3f(Double.parseDouble(ArgArray[0]),
Double.parseDouble(ArgArray[1]),
Double.parseDouble(ArgArray[2])));
This right now is turning the string into a double. That is what
Double.parseDouble();
does.
It looks like you are using floats though, so you can always just use the float parsing method:
Float.parseFloat("String");
That would result with this:
this.makeGrass(new Vector3f(Float.parseFloat(ArgArray[0]),
Float.parseFloat(ArgArray[1]),
Float.parseFloat(ArgArray[2])));
Sorry for the late response, and you are surely welcome for the help. I just love being useful!
OK, so I created a console app that, among other things, takes an array of numbers and prints them out one by one, line by line. Now, I have to take the class that I created for that console app, and pop it into a separate GUI app we're creating. I have all of the other methods working fine, but for the life of me I cannot get the array method to print out correctly. It just gives me the last number I typed into the text field. I'm hoping someone can give me a nudge to help me figure this part out so I can move along, and get to the whole SpringLayout stuff, (the main part of the new assignment) I am limited in what I can show you here because this is a current assignment, so I will have to stick to this stuff as specifically as I can. And please, don't just post the code as an answer, (because then I can't use it), thanks.
Here's what I had for my original project for the array method:
int [] getArray(int x)
{
breakUpNum(x);
return numAry;
}
From there, inside my new class I have this, in an attempt to get it to print:
private class ButtonTest implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
Lab1 tester = new Lab1();
int[] test4 = tester.getArray(num);
for(int i = 0; i < test4.length; i ++)
{
crossTest.getArrCross.setText("" + test4[i]);
}
}
}
Any help pointing me in the right direction would be greatly appreciated, thanks!
setText does just that, sets the text you pass to as the current text content, it does not append it.
If you were to use JTextArea, you could use it's append method...however, for a JTextField you need to have a different approach.
Now you could use getArrCross.setText(getArrCross.getText() + test4[i])...but to quite frank, that's rather inefficient, as each call to setText is going to stage a paint event...
StringBuilder sb = new StringBuilder(128);
for(int i = 0; i < test4.length; i ++)
{
sb.append(test4[i]);
}
crossTest.getArrCross.setText(sb.toString());
Now, if you want to separate each element, you need to add
if (sb.length() > 0) {
sb.append(", ");
}
Before sb.append(test4[i]);
The last bit of actionPerformed in the for loop isn't working right. setText replaces the current text with its argument, and it doesn't seem like you want to do that. To fix it, replace the line in the for loop with this:
crossTest.getArrCross.setText(crossTest.getArrCross.getText() + test4[i]);
here's the deal, I have to make a game that resembles PacMan, with a map, points, ghosts, etc.
The whole thing works as an array[8][8], it reads the positions of walls and the initial position of ghosts from a .txt file, PacMan starts at a fixed location and Fruits are random. Any blank space at the beginning of the game gets filled with a simple point pellet.
I've got the map done, it shows it and everything, but I can't seem to come up with a method that allows the player to control PacMan with the keyboard... This is what I've tried so far...
In the Player class
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
String mov = read.readLine();
if (mov.equals("w"))
{
PacMan.MoveU();
}
It then repeats that for the other movement keys.
The individual Move methods in PacMan class look like this
public static void MoverR()
{
for (int i=0;i<Tablero.length;i++)
{
for (int j=0;j<Tablero.length;j++)
{
if (Tablero[i][j] instanceof PacMan)
Tablero[i][j]=null;
Tablero[i][j+1]=new PacMan();
}
}
}
}
This obviously isn't working, so I'm wondering if anyone can help me with a more efficient way to do this? I really don't mind starting these two classes from scratch...
Thanks.
It always gives me an ArrayOutOfBounds Exception
The ArrayOutOfBounds Exception is caused by Tablero[i][j+1]=new PacMan(); when j == 7, because you try to access to an invalid position (Tablero[i][8]).
anyone can help me with a more efficient way to do this?
You don't need to check the whole array to find out the position of Pacman, you could store the position as a private variable of Pacman, but in that case you shouldn't create a new instance of Pacman every time you need to move it, like you are doing with your current implementation.
One reason why you get ArrayOutOfBoundsException is the fact that in your loop you're moving PacMan to position [i][j +1], where j + 1 may be greater than array length.
You need to check if j + 1 < Tablero.length when you're 'moving' PacMan.
Also you can simply move the same instance of PacMan instead of creating a new one:
...
if (Tablero[i][j] instanceof PacMan) {
if (j + 1 < Tablero.length) {
Tablero[i][j+1] = Tablero[i][j];
Tablero[i][j] = null;
}
}
I am creating a game using a 10x10 2D array. The player starts at the top left hand corner indicated as "P" and the objective is to get the player to avoid obstacles to get to the treasure indicated as "T" located in the lower right corner.
How would I go about making the player move about the grid using commands Up/Down/Left/Right?
Would I use a for loop to count through the elements in the array to designate the move?
Here is what I have so far:
import java.util.Scanner;
import java.util.Random;
public class Adventure {
public static void main(String[] args) {
char grid[][]= new char[10][10];
Scanner move = new Scanner(System.in);
System.out.println("Here is the current game board:");
System.out.println("-------------------------------");
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid.length; j++) {
double random = Math.random();
if(random <=.05) {
grid[i][j]='*';
}
else if(random > .06 && random <= .15) {
grid[i][j]='X';
}
else {
grid[i][j]='.';
}
grid[0][0]='P';
grid[9][9]='T';
System.out.print(grid[i][j]);
}
System.out.println("");
}
System.out.print("Enter your move (U/D/L/R)>");
}
}
you should keep track of the current position of the player and just update those variables.
initial values would be (0,0) as you said.
int px = 0;
int py = 0;
when a move is made, update the variables accordingly:
grid[px][py] = <empty cell>;
switch (move) {
case 'u': py += 1; break;
case 'r': px += 1; break;
...
}
grid[px][py] = 'P';
of course you shouldn't just updated the values "blindly", you should insert some validation logic to follow the rules of the game:
if (grid[px][py] != <obstacle> )
// update player coordinates...
Looks like you're using row-major ordering, judging from the way your board prints out. Based on that, here's what you'll need to do:
First, you need to store the player's position somewhere. Right now it's hardcoded to 0,0.
Second, you need to read in the player's move. That will have to happen in a loop, where you get a move, check if the move is allowed, perform the move, and display the results.
Third, you need to be able to calculate the new position based on the move. Up means row -= 1. Right means column += 1. Etc.
Given the new coordinates, you need to make sure the move is valid. At the very least, you have to stop them from walking off the board, but you may also prevent them from entering a square with an obstacle, etc.
Once you know that the move is valid, you have to update the variables you're storing the current coordinates in.
At the end of the loop, you'll need to redraw the board.
That's the basic gist of it. Right now you are doing everything in main(), and that's okay, but if it were me I would start to split things out into separate methods, like InitializeBoard(), GetNextMove(), CheckIfMoveIsValid(int r, int c), and so on. That way, main() becomes a high-level view of your game loop, and the guts of the different operations are compartmentalized and more easy to deal with. This will require storing off things like your game board into class variables rather than local variables, which should actually make things like obstacle detection easier than it would be currently.
All of the above answers are great. Here are a few suggestions I would make:
Instead of a char two-dimensional array, I would make a custom object, such as Space, and define a two-dimensional array of Spaces (eg, Space[][]). There are a few reasons for this:
You can define a space in a variety of ways (rather than just 1 character). For example, Space[i][j].hasTreasure() can return a boolean to let you know whether or not you found the treasure.
If you want to add functionality later, its as easy as adding an attribute to your Space class. Again, you are not limited to one character here.
More to your question of movement, I would also recommend a few things. Similar to redneckjedi's suggestion of a CheckIfMoveIsValid() method, I would pass the grid and move direction as parameters and return a boolean. To ensure that you do not end up with ArrayIndexOutOfBounds issues, I would also suggest adding a row/column of walls on each side. I would widen the grid out to 12x12 and put a strip of obstacle-type blocks around the outside. This will ensure that you cannot step outside of the grid as hitting a wall will always return 'false' on a valid move.