I am trying to make some movable cars in JFrame(Canvas) to make a game.
I am using this type of code to move the position of the image object.
public void tick() {
z += 1;
}
but it always run once. And it go through JFrame.
How do i make the object to loop infinity like cars?
Related
I have a jpanel that I repaint in a step event. It takes a cars position x and draws it. This works with integers but I'd like to use a double. The car objects x and y are needed to be doubles because I want to rotate and accelerate in a direction. Any ideas? Here's my current code:
public class Map extends JPanel implements ActionListener {
private void step() {
for(int i = 0; i <cars.length; i++) {
Car car = cars[i];
car.move();
repaint(car.getX()-1, car.getY()-1, car.getWidth()+2, car.getHeight()+2);
}
}
}
One possibility is for you to use doubles in your program's model, the classes that describe the state of your system, and use ints (by casting or rounding) in the view -- your GUI graphics code -- when displaying the state of the model.
Another is for you to consider using classes that implement the Shape interface, such as Rectangle2D, Ellipse2D, and Path2D as these use double or float specifiers for positioning
Your current code is broken in that the code is called on the Swing event thread, but appears to attempt to animate within a for loop. That's not going to work, and will only show the starting and finishing state of the animation due to it blocking the Swing event thread. Instead use a Swing Timer to drive the animation.
I've searched for similar threads like this but couldn't find any.
I am wondering if there is a more efficient way of rendering a tile, which only uses 1 image and draws the same image in a grid to cover an area.
I'm using the code below:
public void render(Graphics g) {
for(int r = 0; r <= tilePieces.length; r++) {
for(int c = 0; c <= tilePieces[0].length; c++) {
try {
tilePieces[r][c].render(g);
}
catch(Exception e) {
}
}
}
}
When I create a tile, I also create as many tile pieces (squares) it needs and I store them in an array.
Every time the render() method of the object is called, it loops through the array and calls their render() methods, which draw the image.
There is no lag in the game, but I find this way of doing this inefficient, since I have to create a bunch of objects for one tile and call their render methods.
That's why, I tried drawing the same one image in the method above, instead of calling the render() method of each tile piece, and that caused the game to run like 1 frame per 5 seconds. Which is weird, what is the difference between calling a method to draw your image and drawing your image directly in the loop?
I got this code that gets x,y positions from a motion sensor tracking a hand. The app draws a circle in the middle of the screen and then detects whether the hand is outside the circle. While the hand is outside the circle, a function checks the distance of the hand from the center of the circle. I'm attempting to store the distance data while the hand is outside of the circle in a linked list.
I need to get both the top 5 largest values and the duration for each time the hand is outside the circle.
Here's my code thus far; I've left out a bunch of the code for setting up the motion sensor just for simplicity, so this is semi-pseudo code. In any case, my main issue is getting the values I need from the list. I have the circle class included as well. I do the outside of the circle calculation and how far outside of calculation inside of my circle class.
Please let me know if this makes sense! The motion sensor is reading in data at 200 fps, so efficiency is factor here. On top of that, I am only expecting the hand, going back and forth, to be outside of the circle for a few seconds at a time.
import java.util.*;
LinkedList<Integer> values;
public void setup()
{
size(800, 300);
values = new LinkedList<Integer>();
HandPosition = new PVector(0, 0); //This is getting x,y values from motion sensor
aCircle = new Circle(); //my class just draws a circle to center of screen
aCircle.draw();
}
public void draw()
{
if (aCircle.isOut(HandPosition)) /* detects if movement is outside of circle. Would it make more sense for this to be a while loop? I also need to start a timer as soon as this happens but that shouldn't be hard */
{
values.add(aCircle.GetDistance(HandPosition)); //gets how far the hand is from center of circle and adds it to linked list. Allegedly at least, I think this will work.
/*So I need to get the 5 largest value from inside of my linked list here.
I also need to start a timer*/
}
}
class Circle {
PVector mCenter;
int mRadius;
Circle()
{
// initialize the center position vector
mCenter = new PVector(0,0);
mRadius = 150;
mCenter.set((width/2),(height/2));
}
boolean isOut(PVector Position) //detects if hand position is outside of circle
{
return mCenter.dist(Position) <= mRadius;
}
float GetDistance(PVector Position) //detects how far the hand is from the center of circle
{
return mCenter.dist(Position);
}
void draw() {
ellipse(mCenter.x, mCenter.y, mRadius, mRadius);
}
}
I'm new to Processing as well so don't hold back if any of this works.
You can use Collections.sort(List); here, then take last five element from the list.
Collection.Sort()
I've been trying to figure this out, all I want to do is be able to draw a string for longer than just a frame, but when I call it in the method I want it to flash up then disappear immediately, any advice would be appreciated :) I'm using something like this:
g.drawString("You got a Key!", 100, 100);
I'm doing this in a method which is called after an Item is picked up
public void addItemFound(Graphics g){
ip.mainInventory[ip.getFirstEmptyStack()] = getItemStackFound();
System.out.println(this.getItemFound() + " added");
g.drawString("You Got a Key!", 100, 100);
}
That's the full method if you were interested :) Thanks!Also apologies for the dumb question, i'm a newbie to this :P
I believe that the best way to do this project would be to draw the scene at regular intervals e.g. 10 milliseconds using a Thread.sleep(). This way, you can simply add a variable to show the message for, say, 100 loops (1 second) like this:
private LinkedList<String> drawStringList= new LinkedList<>();
private LinkedList<Integer> drawStringTimeout= new LinkedList<>();
private LinkedList<Integer[]> drawStringPos= new LinkedList<>();
public void addText(String stringToWrite, int posX, int posY, int timeOut) {
drawStringList.add(stringToWrite);
int[] pos = new int[2];
pos[0] = posX;
pos[1] = posY;
drawStringPos.add(pos);
drawStringTimeout.add(timeOut);
}
private void mainLoop() {
...items to be drawn here...
for(int i=0;i<drawStringList.size();i++){
g.drawString(drawStringList.get(i),drawStringPos.get(i)[0],drawStringPos.get(i)[1]);
drawStringTimeout.set(i,drawStringTimeout.get(i)-1);
if(drawStringTimeout.get(i)<=0) {
drawStringList.remove(i);
drawStringTimeout.remove(i);
drawStringPos.remove(i);
}
}
try { Thread.sleep(10); } catch (Exception e) {}
}
In this code, you must add the string you want to draw to drawStringList, add the number of loops you want it to stay for to drawStringTimeout and add the position you would like to draw it in to drawStringPos as an array (you could use a point if you wanted to). I have made a method to do this.
I don't know what Dan300 is trying to tell you to do but that's way, way, way over complicated. Slick2D works on gamestates:
http://slick.ninjacave.com/javadoc/org/newdawn/slick/state/GameState.html
The gamestate has a method called render(). The render() is called every single cycle of the loop to update your screen with drawing information. If you want to draw the text on the screen for a longer time you should be drawing the text somewhere within the stack space of this render() function.
What is happening now is you have a function with one specific purpose that only exists every so briefly: add an item to the player. The game comes across this statement and when adding an item within that 1 cycle the text will be drawn. But the next cycle when the player isn't picking up an item it won't come by that drawString statement and you won't have your string on your screen longer than 1 game cycle.
I'm working on to do my assignment. It is a chess design(AI, GUI not required), I have piece class. The piece class has two variables: color and name. So far I have a "move method" like this in this class.
`
public void move(Piece piece,int x,int y)
{
int a=0;
int b=0;
for(int i=0;i<Board.grid.length;i++) {
for(int r=0;r<Board.grid[i].length;r++) {
if(Board.grid[i][r]==piece)
a=i;
b=r;
if(Board.getisnull(x, y)){
Board.grid[a][b]=null;
Board.grid[x][y]=piece;
}
}
}
Board.grid[u][t]=null;
}
`
In this code, I want to find an index which is the old index of the piece I want to move, then moving it then setting its old index to null but this is not working. I can see the name on screen but not the color. Also, old index is not set to null. How to do it? I started to think using an object(piece) array but how?
Just a small hint:
//finds the piece equal to name and color of our piece.so
if(Board.grid[i][y].equals(name) || Piece.color.equals(color))
This doesn't fit together, since the check is "equal to name OR equal color". I think you want to change it to: if(Board.grid[i][y].equals(name) && Piece.color.equals(color))
Piece.setColor(color);//set this piece's color
Huh? What are you doing that for? Shouln't Piece keep its color all the time?
if(Board.getisnull(x, y)==true)
You're redefining y in your loop so y is not the parameter you passed in to the method.
Basically, I'd redefine the method (to keep is as close to the OP as possible, note that OOP wise there could be even better design, subclassing Piece etc.):
//Board.grid[][] should be a 'Piece[8][8]';
//edit: rename parameters for clarity
public void move( Piece piece,int targetX,int targetY)
{
if( Board.getisnull(targetX, targetY) )//method in other class checks the indexes if null
{
//remove the piece from the field/index
Board.grid[piece.x][piece.y]=null;
//add the piece to the target field and update its position
piece.x = targetX;
piece.y = targetY;
Board.grid[targetX][targetY]=piece;
}
else
{
//handle that case, e.g. by throwing an exeption
}
}
Now you'd get the piece you want to move (which knows its index), calculate the target position and call move(piece, targetX, targetY);