libGDX why does my fori loop not update Sprite position properly? - java

So I created an "UpdateShopPosition" method, that should place Sprites in correct spots on the screen. However when I launch it in the render method, it seems that every Sprite shares the exact same position, not only that but the position keeps moving right and down.
I want MyX and MyY to have a different value for each shopList.get(i) . Is there a problem with the loop or is it because I placed this method in the render() section?
public class ObjectCreator {
public static int rowsX = 4;
public static int rowsY = 5;
public static void UpdateShopPosition(List<Sprite> spriteList){
for (int i = 0; i < spriteList.size(); i++) {
float myX = playerSprite.getX() + ((i + 4) * 100);
if (i > 0){
myX+= i*3;
}
float myY = playerSprite.getY() + 410;
if (i >= rowsX && i < rowsX*2 ) {
myX = myX - 400;
myY = myY - 101;
}
else if (i >= rowsX*2 && i < rowsX*3){
myX = myX - 800;
myY = myY - 202;
}
else if (i >= rowsX*3 && i < rowsX*4){
myX = myX - 1200;
myY = myY - 303;
}
else if (i >= rowsX*4 && i < rowsX*5){
myX = myX - 1600;
myY = myY - 404;
}
else if (i >= rowsX*5 && i < rowsX*6){
myX = myX - 2000;
myY = myY - 505;
}
spriteList.get(i).setPosition(myX, myY);
}
}
public static void CreateUsable(Usables name, Sprite sprite){
GameApp.shopList.add(sprite);
name.setImage(GameApp.shopList.get(0));
}
}
for (int i = 0; i < usableList.size(); i++) {
usableList.get(i).draw(batch);
usableList.get(i).setPosition(playerSprite.getX() - 1200, playerSprite.getY() + 300);
usableList.get(i).setSize(60,60);
// the next (i) should be placed on the next grid, so a little bit to the right
}
I tried to create a method that keeps placing items sprites respectively to my player sprite, I want these sprites to have the same position no matter where I move on the map

Related

Grid Not Returning a Value in Processing 3

I'm trying to make a minesweeper clone using Processing's java. I have managed to create a grid and each tile has a randomized value assigned to it, but for some reason, only the top left tile can be clicked, the rest of the tiles do not return a value. If anyone knows whats wrong with my code or what I could try that would be great, thanks
Here's my Java code:
int realWidth = 500;
int realHeight = 500;
int tilemount = 0;
boolean mousePress = false;
//calls class
Tile[] tile = new Tile[100];
float tileSize = realWidth/10;
//sets size of window
void settings() {
size(realWidth, realHeight);
}
//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
int x = 0;
int y = 0;
for (int i = 0; i < tile.length; i++) {
tile[i] = new Tile(x, y, int(random(-1,9)), tilemount);
x += tileSize;
if (x > realWidth-tileSize) {
x = 0;
y += tileSize;
}
tilemount ++;
}
print("done");
}
//updates each tile in the list
void draw() {
background(50);
for (int i = 0; i < tile.length; i++) {
tile[i].display();
tile[i].tileClicked();
}
//checks if tiles are clicked
clickCheck();
}
//sets up tile class
class Tile {
int x;
int y;
int value;
int tilemount;
Tile(int x, int y, int value, int tilemount) {
this.x = x;
this.y = y;
this.value = value;
this.tilemount = tilemount;
}
//positions the tile based off of display values
void display() {
rect(x, y, tileSize, tileSize);
}
//the problem:
/*if tile is clicked, it should run through all 100 tiles in the list,
detect if the mouse is inside the x value assinged to each tile, and produce the
value of the tile the mouse is currently inside */
void tileClicked() {
if (mousePressed && mousePress == false) {
mousePress = true;
for (int i = 0; i < tile.length; i++) {
//println(tile[i].x, tile[i].y);
//println(tile[2].x, tile[2].y, mouseX, mouseY);
if (mouseX > tile[i].x && mouseX < tileSize && mouseY > tile[i].y && mouseY < tileSize) {
println(i, tile[i].value);
break;
}
}
}
}
}
//Checks if mouse is clicked
void clickCheck() {
if (!mousePressed) {
mousePress = false;
}
}
There is a bit of confusion over classes/objects and global variables in your code.
I say that for a few reasons:
boolean mousePress = false; is a global variable, accessible throughout the sketch, however you are accessing it and changing it from each Tile instance, resetting it's value: you probably meant to use a mousePress property for Tile. This way, each Tile has it's mousePress without interfering with one another.
in tileClicked() you're itereratting through all the tiles, from Tile which means unecessarily doing the loop for each time: each tile can check it's own coordinates and position to know if it's being clicked or not (no need for the loop)
speaking of checking bounds, checking if mouseX < tileSize and mouseY < tileSize will only check for the top left tile: you probably meant mouseX < x + tileSize and mouseY < y + tileSize
Here's a version of your sketch with the above notes applied
(and optional debug text rendering to double check the printed value against the tile):
int realWidth = 500;
int realHeight = 500;
int tilemount = 0;
//calls class
Tile[] tile = new Tile[100];
float tileSize = realWidth/10;
//sets size of window
void settings() {
size(realWidth, realHeight);
}
//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
int x = 0;
int y = 0;
for (int i = 0; i < tile.length; i++) {
tile[i] = new Tile(x, y, int(random(-1,9)), tilemount);
x += tileSize;
if (x > realWidth-tileSize) {
x = 0;
y += tileSize;
}
tilemount ++;
}
println("done");
}
//updates each tile in the list
void draw() {
background(50);
for (int i = 0; i < tile.length; i++) {
tile[i].display();
tile[i].tileClicked();
//checks if tiles are clicked
tile[i].clickCheck();
}
}
//sets up tile class
class Tile {
int x;
int y;
int value;
int tilemount;
boolean mousePress = false;
Tile(int x, int y, int value, int tilemount) {
this.x = x;
this.y = y;
this.value = value;
this.tilemount = tilemount;
}
//positions the tile based off of display values
void display() {
fill(255);
rect(x, y, tileSize, tileSize);
fill(0);
text(value,x + tileSize * 0.5, y + tileSize * 0.5);
}
//the problem:
/*if tile is clicked, it should run through all 100 tiles in the list,
detect if the mouse is inside the x value assinged to each tile, and produce the
value of the tile the mouse is currently inside */
void tileClicked() {
if (mousePressed && mousePress == false) {
mousePress = true;
//println(tile[2].x, tile[2].y, mouseX, mouseY);
if (mouseX > x && mouseX < x + tileSize && mouseY > y && mouseY < y + tileSize) {
println(value);
}
}
}
//Checks if mouse is clicked
void clickCheck() {
if (!mousePressed) {
mousePress = false;
}
}
}
I understand the intent of the mousePress variable, but I'd like to mousePressed() function which you can use to avoid de-bouncing/resetting this value and simplify code a bit.
Here's a version of the above sketch using mousePressed() (and renaming variables a touch to be in line with Java naming conventions):
int realWidth = 500;
int realHeight = 500;
int tileCount = 0;
//calls class
Tile[] tiles = new Tile[100];
float tileSize = realWidth/10;
//sets size of window
void settings() {
size(realWidth, realHeight);
}
//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
int x = 0;
int y = 0;
for (int i = 0; i < tiles.length; i++) {
tiles[i] = new Tile(x, y, int(random(-1,9)), tileCount);
x += tileSize;
if (x > realWidth-tileSize) {
x = 0;
y += tileSize;
}
tileCount ++;
}
println("done");
}
//updates each tile in the list
void draw() {
background(50);
for (int i = 0; i < tiles.length; i++) {
tiles[i].display();
}
}
void mousePressed(){
for (int i = 0; i < tiles.length; i++) {
tiles[i].click();
}
}
//sets up tile class
class Tile {
int x;
int y;
int value;
int index;
Tile(int x, int y, int value, int tileCount) {
this.x = x;
this.y = y;
this.value = value;
this.index = tileCount;
}
//positions the tile based off of display values
void display() {
fill(255);
rect(x, y, tileSize, tileSize);
// optional: display the tile value for debugging purposes
fill(0);
text(value, x + tileSize * 0.5, y + tileSize * 0.5);
}
//the problem:
/*if tile is clicked, it should detect if the mouse is inside the
value assinged to each tile, and produce the
value of the tile the mouse is currently inside */
void click() {
if (mouseX > x && mouseX < x + tileSize && mouseY > y && mouseY < y + tileSize) {
println("index", index, "value", value);
}
}
}
Good start though: keep going!
The rest of the code is good, congrats on using a 1D array for a 2D grid layout (and the logic for resetting the x position on each row). Have fun learning !
I think you did a good job naming functions and classes and what not. From this point, I would recommend breaking your code down so that you can make sure that at least 3 tiles function fully before allowing the tilelength to be something like 100 (for 100 tiles).
so from what I can see:
+ You have 3 apostrophes at the end of your code that need to be removed.
+ you use tile.length but never defined a length variable in your class, so when your for loop runs it has no number to use to determine it's number of cycles.
+ Please double check your logic in the tileClicked function with the help of a truth/logic table: https://en.wikipedia.org/wiki/Truth_table . I didn't look too deeply into this but this looks like an area where one misunderstanding could throw ;
Try adding this.length = 3; in your tile class and then re-run your code to see if more tiles pop up.
And it might be good to use some system.out.println calls to print conditional values out so that you can see the intermeediate results and compare them to what you expect to happen. Just some basic debugging.
Good luck.

i need to program this code with arraylist

anything i do seems to break down my code into unusable rubbish. Note that it is also a mess... but at least it does work almost properly.
Here are some details:
it's sort of a particle system but with images. koffer stands for bag and it has to be a sort of eplosion of rotating bags that get slightly bigger or smaller for the depth effect and they fade away in time and after leaving the screen it should be deleted.
For now i got half of the bags that explode to turn random ways and half of the bags don't do that. They all fade but don't get deleted after leaving the screen. there is no slight resize yet. But most of all i have to use an arraylist() and don't know how to implement that.
here is my code:
Main Class BagEplode:
PImage coffre;
float life = 255;
int i = 0;
Ball [] balls = new Ball [200];
void setup(){
size (600,600,P3D);
noStroke();
smooth();
coffre = loadImage("coffre.png");
for (i = 0; i < balls.length; i ++)
{
balls[i] = new Ball();
}
}
void draw()
{
clear();
life -= 2.5;
for (int i = 0; i < balls.length; i++)
{
if(i <= 4)
{
balls[i].kleur();
image(coffre, balls[i].x, balls[i].y);
tint(255, life);
balls[i].update();
}
//else
//{
//}
}
}
and i got the Class Ball:
class Ball
{
public void kleur(){
}
float x = width/2;
float y = 601;
float vX = random(1,4);
float vY = random(-9,-5);
float sizeX = 0 ;
float sizeY = 0 ;
float draaiHoek = 0;
float angle = random(-3,3);
public void update(){
x += vX ;
y += vY ;
vY += 0.125;
sizeX = 64 ;
sizeY = 64 ;
draaiHoek -=angle;
imageMode(CENTER);
pushMatrix();
translate(x,y);
rotate((radians(draaiHoek)));
image(coffre, 0, 0);
imageMode(CORNER);
popMatrix();
//if (x > width || x < 0 || y > height || y < 0)
//{
//}
}
}
Thanx for helping me in advance. I hope i really can get some pointers.
From my understanding, you need to replace balls array of type- Ball with an ArrayList of type Ball
import java.util.ArrayList;
public class Ball {
PImage coffre;
float life = 255;
int i = 0;
//Ball [] balls = new Ball [200];
ArrayList<Ball> balls= new ArrayList<Ball>();
void setup(){
size (600,600,P3D);
noStroke();
smooth();
coffre = loadImage("coffre.png");
/* for (i = 0; i < balls.length; i ++)
{
balls[i] = new Ball();
}
*/
for(int i=0;i<balls.size();i++)
{
balls.add(new Ball());
}
}
void draw()
{
clear();
life -= 2.5;
/* for (int i = 0; i < balls.length; i++)
{
if(i <= 4)
{
balls[i].kleur();
image(coffre, balls[i].x, balls[i].y);
tint(255, life);
balls[i].update();
}
*/
for (int i = 0; i < balls.size(); i++)
{
if(i <= 4)
{
balls.get(i).kleur();
image(coffre, balls.get(i).x, balls.get(i).y);
tint(255, life);
balls.get(i).update();
}
//else
//{
//}
}
}
}

Nested for loops to create pyramid

I was wondering if someone could help figure this out. I've been trying to display a pyramid using nested for loops and I've only been able to get the first row (base row) working. The pyramid is suppose to have 10 rectangles at the bottom and as it increments up, the rectangle count decreases to 9, 8, 7, 6, etc. I've been looking at this for days and have had no luck.
Thank you!
public class Legos2 extends JFrame {
private int startX;
private int startY;
private int legoWidth;
private int legoHeight;
private int baseLength;
private int arcWidth;
private int arcHeight;
// Constructor
public Legos2() {
super("Jimmy's LEGOs");
startX = 20;
startY = 300;
legoWidth = 50;
legoHeight = 20;
baseLength = 10;
arcWidth = 2;
arcHeight = 2;
}
// The drawings in the graphics context
public void paint(Graphics g)
{
// Call the paint method of the JFrame
super.paint(g);
int currentX = startX;
int currentY = startY;
//row = 0 is the bottom row
for (int row = 1; row <= baseLength; row++)
{
currentX = currentX + legoWidth;
if (row % 2 == 0)
g.setColor(Color.blue);
else
g.setColor(Color.red);
System.out.println(row);
for (int col = 0; col <= baseLength; col++)
{
System.out.println(col);
g.fillRoundRect(currentX, currentY, legoWidth, legoHeight, arcWidth, arcHeight);
}
//currentY = currentY - legoHeight;
}
}
// The main method
public static void main(String[] args) {
Legos2 app = new Legos2();
// Set the size and the visibility
app.setSize(700, 500);
app.setVisible(true);
// Exit on close is clicked
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
The currentY value should be decremented at each iteration of the outer loop: for each row, you want to restart from a lower Y. So you should uncomment the line
//currentY = currentY - legoHeight;
The currentX must be incremented after each column, so at the end of the inner loop, and not at the beginning of the outer loop. And it must be reset to the start X position of the current row before you enter the inner loop.
If you just reset currentX to startX, you'll get a wall of bricks. But you need a pyramid. So there should be one less iteration of the inner loop at each iteration of the outer loop, and the startX should also be incremented after each iteration of the outer loop:
for (int row = 1; row <= baseLength; row++) {
currentX = startX;
if (row % 2 == 0) {
g.setColor(Color.blue);
}
else {
g.setColor(Color.red);
}
System.out.println("row = " + row);
for (int col = 0; col <= baseLength - row; col++) {
System.out.println("col = " + col);
g.fillRoundRect(currentX, currentY, legoWidth, legoHeight, arcWidth, arcHeight);
currentX = currentX + legoWidth;
}
currentY -= legoHeight;
startX += legoWidth / 2;
}

processing FrameBuffer Error

I am trying to make a processing program, but if I use P2D, P3D, or OPENGL mode I get an error:
com.sun.jdi.VMDisconnectedException
at com.sun.tools.jdi.TargetVM.waitForReply(TargetVM.java:285)
at com.sun.tools.jdi.VirtualMachineImpl.waitForTargetReply(VirtualMachineImpl.java:1015)
at com.sun.tools.jdi.PacketStream.waitForReply(PacketStream.java:51)
at com.sun.tools.jdi.JDWP$ObjectReference$InvokeMethod.waitForReply(JDWP.java:4589)
at com.sun.tools.jdi.ObjectReferenceImpl.invokeMethod(ObjectReferenceImpl.java:374)
at processing.mode.java.runner.Runner.findException(Runner.java:701)
at processing.mode.java.runner.Runner.reportException(Runner.java:652)
at processing.mode.java.runner.Runner.exception(Runner.java:595)
at processing.mode.java.runner.EventThread.exceptionEvent(EventThread.java:367)
at processing.mode.java.runner.EventThread.handleEvent(EventThread.java:255)
at processing.mode.java.runner.EventThread.run(EventThread.java:89)
the error message itself varies between P2D and P3D, but they both get a no framebuffer objects available error. I am using processing 2.0b7, please help and let me know if you need more info.
Note: I don't know if this is a separate issue or not, but I am also getting GLSL shader errors to.
Now, here is my code:
Cell[][] Cells = new Cell[50][50];
byte Direction = 1;
byte Times = 1;
int oldwidth = 500;
int oldheight = 500;
void setup() {
size(oldwidth, oldheight, OPENGL);
background(255);
colorMode(HSB,250);
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
Cells[x][y] = new Cell(x * 5, y * 5, 255, x * (width / 50), y * (height / 50), width / 50, height / 50);
}
}
}
void draw() {
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
if (width == oldwidth) Cells[x][y].Width = width / 50;
if (height == oldheight) Cells[x][y].Height = height / 50;
if (Direction == 1){
Cells[x][y].Hue += 5;
if (Cells[x][y].Hue > 250) Cells[x][y].Hue -= 250;
}
if (Direction == 2){
Cells[x][y].Saturation -= 5;
if (Cells[x][y].Saturation < 0) Cells[x][y].Saturation += 500;
}
if (Direction == 3){
Cells[x][y].Hue -= 5;
if (Cells[x][y].Hue < 0) Cells[x][y].Hue += 250;
}
if (Direction == 4){
Cells[x][y].Saturation += 5;
if (Cells[x][y].Saturation > 500) Cells[x][y].Saturation -= 500;
}
Cells[x][y].Draw();
}
}
if (Times == 50){
Times = 1;
if (Direction == 4) Direction = 1; else Direction += 1;
} else Times += 1;
delay(10);
}
class Cell {
int X;
int Y;
int Width;
int Height;
float Hue;
float Saturation;
float Brightness;
Cell(color parC, int parX, int parY, int parWidth, int parHeight) {
Hue = hue(parC);
Saturation = saturation(parC);
Brightness = brightness(parC);
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
Cell(float parHue, float parSaturation, float parBrightness, int parX, int parY, int parWidth, int parHeight) {
Hue = parHue;
Saturation = parSaturation;
Brightness = parBrightness;
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
void Draw() {
if (Saturation > 250) if (Saturation > 500) stroke(color(Hue,0,Brightness)); else stroke(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else stroke(color(Hue,Saturation,Brightness));
if (Saturation > 250) if (Saturation > 500) fill(color(Hue,0,Brightness)); else fill(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else fill(color(Hue,Saturation,Brightness));
rect(X, Y, Width, Height);
}
}
I just realized that it is just that my graphics card does not support OPENGL 2.0

How can I make the image move in a random position?

I have an image inside the panel and it moves in a clockwise direction. Now, I want it to move in a random direction and that is my problem.
Could someone give me an idea how to do it?
Here's what I've tried :
private int xVelocity = 1;
private int yVelocity = 1;
private int x, y;
private static final int RIGHT_WALL = 400;
private static final int UP_WALL = 1;
private static final int DOWN_WALL = 400;
private static final int LEFT_WALL = 1;
public void cycle()
{
x += xVelocity;
if (x >= RIGHT_WALL)
{
x = RIGHT_WALL;
if (y >= UP_WALL)
{
y += yVelocity;
}
}
if (y > DOWN_WALL)
{
y = DOWN_WALL;
if (x >= LEFT_WALL)
{
xVelocity *= -1;
}
}
if (x <= LEFT_WALL)
{
x = LEFT_WALL;
if (y <= DOWN_WALL)
{
y -= yVelocity;
}
}
if (y < UP_WALL)
{
y = UP_WALL;
if (x <= RIGHT_WALL)
{
xVelocity *= -1;
}
}
}
Call a method like this to set a random direction:
public void setRandomDirection() {
double direction = Math.random()*2.0*Math.PI;
double speed = 10.0;
xVelocity = (int) (speed*Math.cos(direction));
yVelocity = (int) (speed*Math.sin(direction));
}
Just noticed that you're cycle method will need a little fixing for this to work.
public void cycle() {
x += xVelocity;
y += yVelocity; //added
if (x >= RIGHT_WALL) {
x = RIGHT_WALL;
setRandomDirection();//bounce off in a random direction
}
if (x <= LEFT_WALL) {
x = LEFT_WALL;
setRandomDirection();
}
if (y >= DOWN_WALL) {
y = DOWN_WALL;
setRandomDirection();
}
if (y <= UP_WALL) {
y = UP_WALL;
setRandomDirection();
}
}
(It works, but this is not the most efficient/elegant way to do it)
And if you want some sort of 'random walk' try something like this:
public void cycle() {
//move forward
x += xVelocity;
y += yVelocity;
if (Math.random() < 0.1) {//sometimes..
setRandomDirection(); //..change course to a random direction
}
}
You can increase 0.1 (max 1.0) to make it move more shaky.
Change
y -= yVelocity;
To
if (y>0) {
y = -1*Random.nextInt(3);
} else {
y = Random.nextInt(3);
}

Categories