How to render sprite array efficiently in j2me game? - java

I am working on a landscape java game.
I have a sprite array like this;
Sprite stickArray[] = new Sprite[10];
and initializing it like this with visibility as false.
for (int j = 0; j < stickArray.length; j++) {
if (stickArray[j] != null) {
stickArray[j].setPosition(stickX, stickY);
stickArray[j].setVisible(false);
}
}
Later I want to position it like one after another vertically on repeating a key.pressBool is false initially.
public void keyRepeatInGame(int keyCode) {
int gameKey = getGameAction(keyCode);
Graphics g = getGraphics();
if (gameKey == FIRE || keyCode == KEY_NUM5) {
pressBool = true;
}
}
Later I have written code like this;
Initially one Sticksprite is there.above this sprite, I want to place each sticks on clalling keyrepeat()in space key.
for (int i = 0; i < stickArray.length; i++) {
if (pressBool) {
if (i == 0) {
stickArray[i].setPosition(stickSprite.getX(),
stickSprite.getY() - stickSprite.getHeight());
stickArray[i].setVisible(true);
} else {
stickArray[i].setPosition(stickArray[i-1].getX(),
stickArray[i-1].getY() - stickArray[i].getHeight());
stickArray[i].setVisible(true);
}
}
}
This code is working partially.Stick is getting added on the sprite,all at once.
How can I change the code to make the sticks repeatedly getting added on calling keyrepeat() only, and make it visible one by one properly?

I changed the code with an additional condition and break statement like this;
if (pressBool) {
if (stickSprite != null && !stickArray[i].isVisible()
&& stickArray[i] != null) {
if (i == 0) {
stickArray[i].setPosition(
stickSprite.getX(),
stickSprite.getY());
stickArray[i].setVisible(true);
break;
} else if (i > 0) {
stickArray[i].setPosition(
stickArray[i].getX(),
stickArray[i - 1].getY()
- stickArray[i].getHeight());
stickArray[i].setVisible(true);
break;
}
}
}
It worked.

Related

Why are my keypresses in processing (java) getting a static/active mode mixing error?

I'm using processing (java) and I'm trying to use an array called input to easily handle keypresses. Here's my code for that:
boolean input[] = {};
void keyPressed() {
input[keyCode] = true;
}
void keyReleased() {
input[keyCode] = false;
}
And so, if this code worked, I could just call this
if (input[32]) { //32 == SPACE
//Do something
}
And the conditional would result to true if the key were pressed, and the statement would get executed, otherwise, it would result to false if the key were released.
However, I'm getting this error:
main.pde:1:1:1:1: Syntax Error - You may be mixing static and active modes.
Why is this?
Thanks for any help.
The following demo will trap spacebar presses. If you want to trap presses for multiple keys you would need to use an array of integers instead of booleans, eg int input[] = new int[4]; then iterate the array when keys are pressed (see second example). Keep in mind that some keys are coded and others are not, eg arrow keys are coded and it takes different code to trap them.
boolean spaceBarPressed = false;
void setup(){
}
void draw(){
if(spaceBarPressed){
println("Space bar pressed.");
} else {
println("Space bar released.");
}
}
void keyPressed() {
if(key == 32){
spaceBarPressed = true;
}
}
void keyReleased() {
if(key == 32){
spaceBarPressed = false;
}
}
Second Example for key array:
/*
Will trap key presses for an array of ascii keys
*/
int input[] = new int[2];
int keySelected;
boolean keyDwn = false;
void setup() {
input[0] = 32;
input[1] = 65;
}
void draw() {
switch(keySelected) {
case 32:
if (keyDwn) {
println("spacebar dwn.");
} else {
println("spacebar up.");
}
break;
case 65:
if (keyDwn) {
println("key A down.");
} else {
println("key A up.");
}
break;
}
}
void keyPressed() {
for (int x = 0; x < input.length; x++) {
if (input[x] == 32 || input[x] == 65) {
keySelected = keyCode;
keyDwn = true;
}
}
}
void keyReleased() {
for (int x = 0; x < input.length; x++) {
if (input[x] == 32 || input[x] == 65) {
keySelected = keyCode;
keyDwn = false;
}
}
}

Why are variable changes not persisting a method call?

I'm trying to program a bug to move around an array attached to a custom Room object, whilst keeping count of how many times each tile has been stepped on.
The Room object is working properly, as are the movement and the counting. However, the bug's coordinates, bugX and bugY, are somehow reverting to 0 after exiting the nextMove method. Their values only revert when exiting the method; even the last line of code in the nextMove method itself uses their new values.
Relevant portion of the method is attached, but other sections can be added upon request.
if (dirNum == 0 && bugY < length-1) //Move up
bugY++;
else if (dirNum == 1 && bugX < width-1) //Move right
bugX++;
else if (dirNum == 2 && bugY > 0) //Move down
bugY--;
else if (dirNum == 3 && bugX > 0) //Move left
bugX--;
else {
System.out.println("Error: Cannot move " + direction + ".");
canMove = false;
dirNum = generator.nextInt(4);
continue;
}
This is the context for the command itself.
while (endSim == false) {
nextMove(bugX, bugY);
System.out.print(room.printRoom() + "\n\nNext move? (y/n) ");
simSentinel = in.next();
if (simSentinel.charAt(0) == 'n')
endSim = true;
}
The declarations where the starting coordinates are assigned aren't inside any loops, let alone where the variable itself is called.
The problem is the one described by #T.J.Crowder in his answer though applied to java.
Variables passed as parameters in java are passed by value. If the value is changed by the method receiving the parameter, the change only affects the value inside that method. The "outside" value doesn't change.
What you can do is to encapsulate the coords in an object and pass the encapsulating object as a parameter.
Then the method will receive the object by value, and change it's state (instead of the value of the object).
For a deeper understanding see this question
EDIT I:
I cleand up the code a bit. Though it is is missing the declaration of room and simSentinel, if you add that you should have a running example.
public class Bug{
public int x=0;
public int y=0;
}
public class SimpleSim {
private int dirNum = 0;
private int length = 20;
private int width = 20;
private boolean canMove = true;
private Random generator = new Random();
private boolean endSim = false;
public static void main(String [] args) {
SimpleSim simpleSim = new SimpleSim();
simpleSim.start();
}
private void start() {
Bug myBug = new Bug();
// Give the bug some initial x, y values.
myBug.x = 0;
myBug.y = 0;
while (endSim == false) {
nextMove(myBug);
System.out.print(room.printRoom() + "\n\nNext move? (y/n) ");
simSentinel = in.next();
if (simSentinel.charAt(0) == 'n')
endSim = true;
}
}
}
public void nextMove(Bug bug){
if (dirNum == 0 && bug.y < length-1) //Move up
bug.y++;
else if (dirNum == 1 && bug.x < width-1) //Move right
bug.x++;
else if (dirNum == 2 && bug.y > 0) //Move down
bug.y--;
else if (dirNum == 3 && bug.x > 0) //Move left
bug.x--;
else {
System.out.println("Error: Cannot move " + "?" + ".");
canMove = false;
dirNum = generator.nextInt(4);
}
}
}
It seems that you are passing your bugX and bugY parameters by value. In this case, changing their value inside the method won't affect their values outside the method.
You may want to make your nextMove method return the new values for bugX and bugY after they are computed so that you can gather them back into your actual bugX and bugY variables

I'm trying to delete an object in my world that is saved in an ArrayList but it doesn't work

I use dyn4j physics engine (although I don't think it's relevant for my question).
I don't get any errors but if I press the right mouse button on one of the objects it doesn't delete the object.
Does anyone know what might be the problem?
Here I add the objects to my world:
public void mouseClicked(MouseEvent e) {
double x = e.getPoint().getX()/100;
double y = e.getPoint().getY()/100;
if (addBlocks.isSelected()) {
BodyFixture fblock = new BodyFixture(Geometry.createRectangle(1,1));
dblock = new Body();
if (e.getButton() == MouseEvent.BUTTON1) {
dblock.addFixture(fblock);
dblock.getTransform().setTranslation(x,y);
dblock.setMass(MassType.NORMAL);
dblock.getFixture(0).setRestitution(0.3);
world.addBody(dblock);
gameObjects.add(new GameObject("dirtblock.png", dblock, new Vector2(0, 0), 0.8));
}
}
}
And here I'm trying to delete them:
if (e.getButton() == MouseEvent.BUTTON3) {
for (int i = 0; i < gameObjects.size(); i++) {
if (gameObjects.get(i).contains(e.getPoint())) {
world.removeBody(gameObjects.get(i).body);
gameObjects.remove(i);
}
}
}
Usually when you are deleting items with index in a loop you start the loop at the end of the collection due to indices changing i.e. try this:
if (e.getButton() == MouseEvent.BUTTON3) {
for (int i = gameObjects.size() - 1; i >= 0 ; i--) {
if (gameObjects.get(i).contains(e.getPoint())) {
world.removeBody(gameObjects.get(i).body);
gameObjects.remove(i);
}
}
}

Collision detection inside the same ArrayList

After searching around over the course of a few days, I have not found a solution. I have an ArrayList of collision elements that I want to iterate over and calculate collisions for. I have made several similar attempts, but I am currently stumped.
Collision method (called once a game-tick)
public void iterateCollision()
{
if(iterateBoxes)
{
if(iterateBoxes)
{
for(int i=0;i<boxPool.size();i++)
{
for(int j=i+1;j<boxPool.size();j++)
{
if(!(boxPool.get(i).equals(boxPool.get(j))) && checkCollision(boxPool.get(i), boxPool.get(j)))
{
boxPool.get(i).colliding = true;
boxPool.get(j).colliding = true;
}
}
}
}
}
}
Here is the collision detection method for those of you who would like to review it:
public boolean checkCollision(BaseAABB box1, BaseAABB box2)
{
//This is just to get the center vector of the bounding boxes.
Vector2f c1 = getAABBCenter(box1);
Vector2f c2 = getAABBCenter(box2);
if(Math.abs(c1.x - c2.x) > (box1.width + box2.width)) return false;
if(Math.abs(c1.y - c2.y) > (box1.height + box2.height)) return false;
return true;
}
You forgot to add a condition that i != j
I suspect that you should replace the following condition:
boxPool.get(i) != boxPool.get(j)
with:
!boxPool.get(i).equals(boxPool.get(j))
Further, there's no need to double loop over all the elements, you can always start with j = i + 1 and then you don't have to check that i != j:
for(int i=0;i<boxPool.size();i++)
{
// V
for(int j=i+1;j<boxPool.size();j++) // <-- this line has changed!
{
if(boxPool.get(i) != boxPool.get(j) && checkCollision(boxPool.get(i), boxPool.get(j)))
{
boxPool.get(i).colliding = true;
boxPool.get(j).colliding = true;
}
}
}

Uno Project: Making sure that a illegal plays return correctly?

I am writing a chunk of program to play Uno with other classes. My Uno project is almost finished, but I need to be sure that the part which checks to make sure that on moves after a Wild Card is played, I play either a legal card or return a -1. Here is my code:
import java.util.*;
public class AlexaL_UnoPlayer implements UnoPlayer
{
public int play(List<Card> hand, Card upCard, Color calledColor, GameState state)
{
int play = -1;
boolean haveWild = false;
boolean matchesWildCall = false;
int indexOfWild = 0;
//turn number of cards all players are holding into ints for later use
int[] array = state.getNumCardsInHandsOfUpcomingPlayers();
int playerNext = array[0];
int playerTwoNext = array[1];
int playerBefore = array[2];
Color upCardColor = upCard.getColor();
for(int i = 0; i < hand.size(); i++)
{
//see if I have any wilds
if(hand.get(i).getRank().equals(Rank.WILD) || hand.get(i).getRank().equals (Rank.WILD_D4))
{
haveWild = true;
indexOfWild = i;
}
//set upCard color to calledColor if wild or wild_d4 are played
if (upCard.getRank().equals(Rank.WILD) || upCard.getRank().equals(Rank.WILD_D4))
{
upCardColor = calledColor;
}
//always play a card matching rank of upCard, if possible, or play the first in hand which matches color
if(hand.get(i).getColor().equals(upCardColor))
{
if(hand.get(i).getNumber() == upCard.getNumber())
{
play = i;
}
}
//if cornered(no matching number or color), play a wild
else if(haveWild == true)
{
play = indexOfWild;
}
//hold reverse cards until person next after me has less cards than person before me
if(hand.get(i).getRank().equals(Rank.REVERSE) && playerNext < playerBefore)
{
play = i;
}
//play skips when person next to me has less cards than me
if((hand.get(i).getRank().equals(Rank.SKIP) || hand.get(i).getRank().equals(Rank.DRAW_TWO)) && playerNext < hand.size())
{
play = i;
}
}
return play;
}
public Color callColor(List<Card> hand)
{
//strategy: change the color to the one i'm holding the most of
Color changeTo = Color.GREEN;
int numBlues = 0;
int numGreens = 0;
int numReds = 0;
int numYellows = 0;
//find out how many of each color i'm holding
for(int i = 0; i < hand.size(); i++)
{
if(hand.get(i).getColor().equals(Color.BLUE))
{
numBlues++;
}
else if(hand.get(i).getColor().equals(Color.RED))
{
numReds++;
}
else if(hand.get(i).getColor().equals(Color.GREEN))
{
numGreens++;
}
else if(hand.get(i).getColor().equals(Color.YELLOW))
{
numYellows++;
}
}
//find out which i'm holding the most of and call that color
//if no majority, return my favorite color(green)
if(numBlues > numReds && numBlues > numGreens && numBlues > numYellows)
{
changeTo = Color.BLUE;
}
else if(numReds > numBlues && numReds > numGreens && numReds > numYellows)
{
changeTo = Color.RED;
}
else if(numGreens > numBlues && numGreens > numYellows && numGreens > numReds)
{
changeTo = Color.GREEN;
}
else if(numYellows > numBlues && numYellows > numGreens && numYellows > numReds)
{
changeTo = Color.YELLOW;
}
else
{
changeTo = Color.GREEN;
}
return changeTo;
}
}
For some reason, my output is telling me this:
You were given this hand:
0. G7
1. G5
2. G+2
and the up card was: W
and the called color was: YELLOW
and you (wrongly) returned 2.
Valid plays would have included: -1
Can anyone provide some insight on why I am getting this error and how to fix it? Much appreciated!
Based on just this code, it is hard to say what is wrong with your implementation.
Did you try step-by-step debugging of your play function?
Alternately, it would be beneficial to instrument your code with more trace statements to better figure out where the issue might be occurring.
For example:
Every where your play variable gets assigned a value, print its value to console with some context of where you are in code.
if(hand.get(i).getNumber() == upCard.getNumber())
{
play = i;
System.out.println("number match step: play = " + play ); // You can add such a line
}
This should give you an idea as to when play's value is getting mutated to 2 unexpectedly.
Just clutching at straws here, but what are the expected values of getColor and getNumber for wild cards.
In case you have them set to Green or 2 respectively, it might explain the output you are seeing because of the following fragment of code.
//always play a card matching rank of upCard, if possible, or play the first in hand which matches color
if(hand.get(i).getNumber() == upCard.getNumber())
{
play = i;
}
else if(hand.get(i).getColor() == upCardColor)
{
play = i;
}

Categories