get an specific object from my arrayList(Java) - arraylist

hi my problem is that in my code i am calling a method that calculates the different between 2 point and then if that distance is less that 7 it will call another class method that should change the color of the target to red... my problem is that in my arraylist i have 3 or five or depends on the user input targets... so how can i specify the object in my arraylist that is going to be change of color>??? this is my code
package project1;
import java.util.*;
import javax.swing.*;
/**
*
* #author Elvis De Abreu
*/
public class TargetGallery
{
/**ArrayList of Targets initialize as a private*/
private ArrayList<Target> mytargets = new ArrayList<>();
/**Static object for the Target class*/
static Target tg = new Target();
/**Static object for the RifleSite class*/
static RifleSite rs = new RifleSite();
/**Static object for the TargetGallery class*/
static TargetGallery tgy = new TargetGallery();
/**the number of targets input by the user as private*/
private int number = 0;
/**array that store the distance between 2 point for each target*/
private double[] total;
/**
* Method that build the background of the canvas
* with a picture as a environment
*/
private void buildWorld()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(75, 130, "bath.jpeg", 450, 285);
}
/**
* Method that draw a weapon in the middle of the
* canvas as a shooter weapon
*/
private void drawShooter()
{
StdDraw.setXscale(0, 250);
StdDraw.setYscale(0, 250);
StdDraw.picture(125, 0, "weapon.png", 80, 45);
}
/**
* randomly generates X locations for the targets
* add them into the array list
*/
private void createTargets()
{
double x = 125;
double y = 175;
double radius = 7;
String input = JOptionPane.showInputDialog("Type a number" +
"between 2 and 5");
number = Integer.parseInt(input);
for(int i = 0; i < number; i++)
{
Target targ = new Target(x, y, radius);
mytargets.add(targ);
Random rand = new Random();
x = rand.nextInt(400) + 10;
for (Target e: mytargets)
{
if ((e.getX() <= (x+10)) || (e.getX() >= (x-10)))
{
mytargets.clear();
i--;
continue;
}
}
}
}
/**
* Method that run different methods which start the program
*/
public void run()
{
tgy.buildWorld(); //call the buildWorld method
tgy.drawShooter(); //call the drawShooter method
tgy.createTargets(); //call the createTarget method
tgy.simulate(); //call the simulate method
}
/**
* calculates the distance between the RifleSite and the Targets
*/
public void calcDistance()
{
//variable declaration/initialization
double distance;
double distance1;
int i = 0;
total = new double[number];
//for each loop to calculate x and y location of RifleSite and Targets
for (Target e: mytargets)
{
distance = Math.pow(e.getX()-rs.getX(), 2.0);
distance1 = Math.pow(e.getY()-rs.getY(), 2.0);
total[i++] = Math.sqrt(distance + distance1);
}
}
/**
* Method that simulates the game
*/
public void simulate()
{
//Variable declaration/initialization
boolean alive = true;
for(Target e: mytargets)
{
e.drawAlive();
}
rs.drawRifleSite();
//loop that will run while there is still targets alive or user press q
while(alive == true)
{
//if user press a key this
if (StdDraw.hasNextKeyTyped())
{
char ch = StdDraw.nextKeyTyped(); //store the key pressed
//if person press Q will quit the program
if (ch == 'q')
{
int done = JOptionPane.showConfirmDialog(null,
"The Program will close now bye :)");
System.exit(0);
}
else if (ch == 'f')
{
tgy.calcDistance(); //calculates the distance
//if statement to check if the distance if less than radius
for(int i = 0; i < number; i++)
{
if (total[i] <= 7)
{
//THIS IS WHERE MY METHOD SHOULD GO
//SHOULD BE SOMETHING LIKE E.drawDead
}
}
}
}
}
}
/**
* Method for the main of the Program
* #param args the command line arguments
*/
public static void main(String[] args)
{
}
}

Like this:mytargets.get(INDEX GO HERE)
i Hope that helps
(the index starts from 0)
For example:
Target t=mytargets.get(0);
if ((t.getX() > 10) && (t.getY() > 10))
{
//blablabla
}

Related

How to change what block is at certain coordinates?

I am trying to recreate the mod in the YouTuber TommyInnit's video "Minecraft’s Laser Eye Mod Is Hilarious" as me and my friends wish to use it but we couldn't find it on the internet, and I have taken code from here for raycasting and also set up a keybind, but I cannot figure out how to setb the block you are looking at. I have tried to manage to get the block and set it but I can only find how to make new blocks that don't yet exist. My code is the following, with the block code being on line 142:
package net.laser.eyes;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.text.LiteralText;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.event.client.ClientTickCallback;
import net.fabricmc.api.*;
import net.fabricmc.fabric.api.client.rendering.v1.*;
import net.minecraft.block.*;
import net.minecraft.client.*;
import net.minecraft.client.gui.*;
import net.minecraft.client.util.math.*;
import net.minecraft.entity.*;
import net.minecraft.entity.decoration.*;
import net.minecraft.entity.projectile.*;
import net.minecraft.text.*;
import net.minecraft.util.hit.*;
import net.minecraft.util.math.*;
import net.minecraft.world.*;
public class main implements ModInitializer {
#Override
public void onInitialize() {
KeyBinding binding1 = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.laser-eyes.shoot", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, "key.category.laser.eyes"));
HudRenderCallback.EVENT.register(main::displayBoundingBox);
ClientTickCallback.EVENT.register(client -> {
while (binding1.wasPressed()) {
client.player.sendMessage(new LiteralText("Key 1 was pressed!"), false);
}
});
}
private static long lastCalculationTime = 0;
private static boolean lastCalculationExists = false;
private static int lastCalculationMinX = 0;
private static int lastCalculationMinY = 0;
private static int lastCalculationWidth = 0;
private static int lastCalculationHeight = 0;
private static void displayBoundingBox(MatrixStack matrixStack, float tickDelta) {
long currentTime = System.currentTimeMillis();
if(lastCalculationExists && currentTime - lastCalculationTime < 1000/45) {
drawHollowFill(matrixStack, lastCalculationMinX, lastCalculationMinY,
lastCalculationWidth, lastCalculationHeight, 2, 0xffff0000);
return;
}
lastCalculationTime = currentTime;
MinecraftClient client = MinecraftClient.getInstance();
int width = client.getWindow().getScaledWidth();
int height = client.getWindow().getScaledHeight();
Vec3d cameraDirection = client.cameraEntity.getRotationVec(tickDelta);
double fov = client.options.fov;
double angleSize = fov/height;
Vector3f verticalRotationAxis = new Vector3f(cameraDirection);
verticalRotationAxis.cross(Vector3f.POSITIVE_Y);
if(!verticalRotationAxis.normalize()) {
lastCalculationExists = false;
return;
}
Vector3f horizontalRotationAxis = new Vector3f(cameraDirection);
horizontalRotationAxis.cross(verticalRotationAxis);
horizontalRotationAxis.normalize();
verticalRotationAxis = new Vector3f(cameraDirection);
verticalRotationAxis.cross(horizontalRotationAxis);
HitResult hit = client.crosshairTarget;
if (hit.getType() == HitResult.Type.MISS) {
lastCalculationExists = false;
return;
}
int minX = width;
int maxX = 0;
int minY = height;
int maxY = 0;
for(int y = 0; y < height; y +=2) {
for(int x = 0; x < width; x+=2) {
if(minX < x && x < maxX && minY < y && y < maxY) {
continue;
}
Vec3d direction = map(
(float) angleSize,
cameraDirection,
horizontalRotationAxis,
verticalRotationAxis,
x,
y,
width,
height
);
HitResult nextHit = rayTraceInDirection(client, tickDelta, direction);//TODO make less expensive
if(nextHit == null) {
continue;
}
if(nextHit.getType() == HitResult.Type.MISS) {
continue;
}
if(nextHit.getType() != hit.getType()) {
continue;
}
if (nextHit.getType() == HitResult.Type.BLOCK) {
if(!((BlockHitResult) nextHit).getBlockPos().equals(((BlockHitResult) hit).getBlockPos())) {
continue;
}
} else if(nextHit.getType() == HitResult.Type.ENTITY) {
if(!((EntityHitResult) nextHit).getEntity().equals(((EntityHitResult) hit).getEntity())) {
continue;
}
}
if(minX > x) minX = x;
if(minY > y) minY = y;
if(maxX < x) maxX = x;
if(maxY < y) maxY = y;
}
}
lastCalculationExists = true;
lastCalculationMinX = minX;
lastCalculationMinY = minY;
lastCalculationWidth = maxX - minX;
lastCalculationHeight = maxY - minY;
drawHollowFill(matrixStack, minX, minY, maxX - minX, maxY - minY, 2, 0xffff0000);
LiteralText text = new LiteralText("Bounding " + minX + " " + minY + " " + width + " " + height + ": ");
client.player.sendMessage(text.append(getLabel(hit)), true);
//SET THE BLOCK (maybe use hit.getPos(); to find it??)
}
private static void drawHollowFill(MatrixStack matrixStack, int x, int y, int width, int height, int stroke, int color) {
matrixStack.push();
matrixStack.translate(x-stroke, y-stroke, 0);
width += stroke *2;
height += stroke *2;
DrawableHelper.fill(matrixStack, 0, 0, width, stroke, color);
DrawableHelper.fill(matrixStack, width - stroke, 0, width, height, color);
DrawableHelper.fill(matrixStack, 0, height - stroke, width, height, color);
DrawableHelper.fill(matrixStack, 0, 0, stroke, height, color);
matrixStack.pop();
}
private static Text getLabel(HitResult hit) {
if(hit == null) return new LiteralText("null");
switch (hit.getType()) {
case BLOCK:
return getLabelBlock((BlockHitResult) hit);
case ENTITY:
return getLabelEntity((EntityHitResult) hit);
case MISS:
default:
return new LiteralText("null");
}
}
private static Text getLabelEntity(EntityHitResult hit) {
return hit.getEntity().getDisplayName();
}
private static Text getLabelBlock(BlockHitResult hit) {
BlockPos blockPos = hit.getBlockPos();
BlockState blockState = MinecraftClient.getInstance().world.getBlockState(blockPos);
Block block = blockState.getBlock();
return block.getName();
}
private static Vec3d map(float anglePerPixel, Vec3d center, Vector3f horizontalRotationAxis,
Vector3f verticalRotationAxis, int x, int y, int width, int height) {
float horizontalRotation = (x - width/2f) * anglePerPixel;
float verticalRotation = (y - height/2f) * anglePerPixel;
final Vector3f temp2 = new Vector3f(center);
temp2.rotate(verticalRotationAxis.getDegreesQuaternion(verticalRotation));
temp2.rotate(horizontalRotationAxis.getDegreesQuaternion(horizontalRotation));
return new Vec3d(temp2);
}
private static HitResult rayTraceInDirection(MinecraftClient client, float tickDelta, Vec3d direction) {
Entity entity = client.getCameraEntity();
if (entity == null || client.world == null) {
return null;
}
double reachDistance = 5.0F;
HitResult target = rayTrace(entity, reachDistance, tickDelta, false, direction);
boolean tooFar = false;
double extendedReach = 6.0D;
reachDistance = extendedReach;
Vec3d cameraPos = entity.getCameraPosVec(tickDelta);
extendedReach = extendedReach * extendedReach;
if (target != null) {
extendedReach = target.getPos().squaredDistanceTo(cameraPos);
}
Vec3d vec3d3 = cameraPos.add(direction.multiply(reachDistance));
Box box = entity
.getBoundingBox()
.stretch(entity.getRotationVec(1.0F).multiply(reachDistance))
.expand(1.0D, 1.0D, 1.0D);
EntityHitResult entityHitResult = ProjectileUtil.raycast(
entity,
cameraPos,
vec3d3,
box,
(entityx) -> !entityx.isSpectator() && entityx.collides(),
extendedReach
);
if (entityHitResult == null) {
return target;
}
Entity entity2 = entityHitResult.getEntity();
Vec3d hitPos = entityHitResult.getPos();
if (cameraPos.squaredDistanceTo(hitPos) < extendedReach || target == null) {
target = entityHitResult;
if (entity2 instanceof LivingEntity || entity2 instanceof ItemFrameEntity) {
client.targetedEntity = entity2;
}
}
return target;
}
private static HitResult rayTrace(
Entity entity,
double maxDistance,
float tickDelta,
boolean includeFluids,
Vec3d direction
) {
Vec3d end = entity.getCameraPosVec(tickDelta).add(direction.multiply(maxDistance));
return entity.world.raycast(new RaycastContext(
entity.getCameraPosVec(tickDelta),
end,
RaycastContext.ShapeType.OUTLINE,
includeFluids ? RaycastContext.FluidHandling.ANY : RaycastContext.FluidHandling.NONE,
entity
));
}
}
Firstly, I heavily recommend following the standard Java naming conventions as it will make your code more understandable for others.
The technical name for a block present in the world at a specific position is a "Block State", represented by the BlockState class.
You can only change the block state at a specific position on the server-side. Your raycasting code in ran on the client-side, so you need to use the Fabric Networking API. You can see the server-side Javadoc here and the client-side Javadoc here.
Thankfully, Fabric Wiki has a networking tutorial so you don't have to read all that Javadoc. The part that you're interested in is "sending packets to the server and receiving packets on the server".
Here's a guide specific for your use case:
Introduction to Networking
Minecraft operates in two different components; the client and the server.
The client is responsible for doing jobs such as rendering and GUIs, while the server is responsible for handling the world storage, entity AI etc. (talking about logical client and server here)
The physical server and physical client are the actual JAR files that are run.
The physical (dedicated) server contains only the logical server, while a physical client contains both a logical (integrated) server and a logical client.
A diagram that explains it can be found here.
So, the logical client cannot change the state of the logical server (e.g. block states in a world), so packets have to be sent from the client to the server in order for the server to respond.
The following code is only example code, and you shouldn't copy it! You should think about safety precautions like preventing cheat clients from changing every block. Probably one of the most important rules in networking: assume the client is lying.
The Fabric Networking API
Your starting points are ServerPlayNetworking and ClientPlayNetworking. They are the classes that help you send and receive packets.
Register a listener using registerGlobalReceiver, and send a packet by using send.
You first need an Identifier in order to separate your packet from other packets and make sure it is interpreted correctly. An Identifier like this is recommended to be put in a static field in your ModInitializer or a utility class.
public class MyMod implements ModInitializer {
public static final Identifier SET_BLOCK_PACKET = new Identifier("modid", "setblock");
}
(Don't forget to replace modid with your mod ID)
You usually want to pass data with your packets (e.g. block position and block to change to), and you can do so with a PacketByteBuf.
Let's Piece This all Together
So, we have an Identifier. Let's send a packet!
Client-Side
We will start by creating a PacketByteBuf and writing the correct data:
private static void displayBoundingBox(MatrixStack matrixStack, float tickDelta) {
// ...
PacketByteBuf data = PacketByteBufs.create();
buf.writeBlockPos(hit.getPos());
// Minecraft doesn't have a way to write a Block to a packet, so we will write the registry name instead
buf.writeIdentifier(new Identifier("minecraft", "someblock" /*for example, "stone"*/));
}
And now sending the packet
// ...
ClientPlayNetworking.send(SET_BLOCK_PACKET, buf);
Server-Side
A packet with the SET_BLOCK_PACKET ID has been sent, But we also need to listen and receive it on the server-side. We can do that by using ServerPlayNetworking.registerGlobalReceiver:
#Override
public void onInitialize() {
// ...
// This code MUST be in onInitialize
ServerPlayNetworking.registerGlobalReceiver(SET_BLOCK_PACKET, (server, player, handler, buf, sender) -> {
});
}
We are using a lambda expression here. For more info about lambdas, Google is your friend.
When receiving a packet, code inside your lambda will be executed on the network thread. This code is not allowed to modify anything related to in-game logic (i.e. the world). For that, we will use server.execute(Runnable).
You should read the buf on the network thread, though.
ServerPlayNetworking.registerGlobalReceiver(SET_BLOCK_PACKET, (server, player, handler, buf, sender) -> {
BlockPos pos = buf.readBlockPos(); // reads must be done in the same order
Block blockToSet = Registry.BLOCK.get(buf.readIdentifier()); // reading using the identifier
server.execute(() -> { // We are now on the main thread
// In a normal mod, checks will be done here to prevent the client from setting blocks outside the world etc. but this is only example code
player.getServerWorld().setBlockState(pos, blockToSet.getDefaultState()); // changing the block state
});
});
Once again, you should prevent the client from sending invalid locations

JavaFX: Linking variables correctly for EventHandler (Timeline)

I need to set up a simulation of a nuclear power plant in JavaFX. The GUI is working perfectly, but I've got problems with getting the simulation run. I have to use a Timeline (as EventHandler) for this, the handler updates the radiation value in each cell every single tick. The radiation is displayed as a circle on each cell. The higher the radiation, the bigger should the circle be. For this, I made an if-else-statement.
The problem is: The if-statement cannot access the variables from the EventHandler. But this is necessary to update the circle size each tick. I already tried to put the if-statements right into the EventHandler, but then, no circles have been shown anymore on my GUI.
These are the three classes so far:
EDIT: I put the if-statements into the Event Handler, new code below.
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class NuclearPowerPlant extends Application {
private static final int HEIGHT = 50;
private static final int WIDTH = 55;
private static final int CELL_SIZE = 40;
#Override
public void start(Stage stage) {
stage.setScene(new Scene(createContent()));
stage.show();
}
private Parent createContent() {
Pane root = new Pane();
root.setPrefSize((WIDTH - 40) * CELL_SIZE, (HEIGHT - 40) * CELL_SIZE); // Size of displayed window
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
Cell cell = new Cell(x, y);
root.getChildren().add(cell);
}
}
return root;
}
public static void main(String[] args) {
launch(args);
}
}
Cell:
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.util.Duration;
public class Cell extends StackPane {
private static final int CELL_SIZE = 40;
int x;
int y;
private Rectangle cell;
private Circle radiation; // Radiation is displayed as a circle
int circlesize; // Size of the circle (the higher the radiation, the bigger the circle)
double radiationvalue = 5000; // Initializing of the radiation value of all cells at the beginning (air in all cells)
private Text symbol; // For Explosion
double activity;
double reflection;
public Cell(int x, int y) { // Konstruktor fuer die Zelle
setTranslateX(x * CELL_SIZE);
setTranslateY(y * CELL_SIZE);
cell = new Rectangle(CELL_SIZE - 2, CELL_SIZE - 2, Color.BLUE);
cell.setStroke(Color.WHITE);
EventHandler<ActionEvent> handlerUpdateRadiationvalue = event -> {
double newradiationvalue = activity + reflection * 500;
// System.out.println(newradiationvalue);
if (newradiationvalue < 1000) {
this.circlesize = 2;
} else if (newradiationvalue >= 1000 && newradiationvalue < 3000) {
this.circlesize = 5;
} else if (newradiationvalue >= 3000 && newradiationvalue < 5000) {
this.circlesize = 8;
} else if (newradiationvalue >= 5000 && newradiationvalue < 7000) {
this.circlesize = 11;
} else if (newradiationvalue >= 7000 && newradiationvalue < 9000) {
this.circlesize = 14;
} else if (newradiationvalue >= 9000 && newradiationvalue < 10000) {
this.circlesize = 18;
}
// Explosion:
else if (newradiationvalue >= 10000) {
circlesize = 0;
cell.setFill(Color.RED);
symbol = new Text("X");
symbol.setFont(Font.font(38));
}
};
KeyFrame keyframe = new KeyFrame(Duration.seconds(0.02), handlerUpdateRadiationvalue);
Timeline tl = new Timeline();
tl.getKeyFrames().addAll(keyframe);
tl.setCycleCount(Timeline.INDEFINITE);
tl.play();
radiation = new Circle(circlesize, Color.BLACK);
getChildren().add(cell);
if (radiationvalue < 10000) {
getChildren().add(radiation);
} else {
getChildren().add(symbol);
}
// Context Menu for material change:
ContextMenu contextMenu = new ContextMenu();
MenuItem air = new MenuItem("Luft");
air.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.AIR.getActivity();
reflection = Material.AIR.getReflection();
cell.setFill(Color.BLUE);
}
});
MenuItem uranium = new MenuItem("Uran");
uranium.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.URANIUM.getActivity();
reflection = Material.URANIUM.getReflection();
cell.setFill(Color.GREEN);
}
});
MenuItem lead = new MenuItem("Blei");
lead.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.LEAD.getActivity();
reflection = Material.LEAD.getReflection();
cell.setFill(Color.GREY);
}
});
MenuItem ruleblock = new MenuItem("Regelblock");
ruleblock.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
activity = Material.RULEBLOCK.getActivity();
reflection = Material.RULEBLOCK.getReflection();
cell.setFill(Color.YELLOW);
}
});
contextMenu.getItems().addAll(air, uranium, lead, ruleblock);
cell.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>() {
#Override
public void handle(ContextMenuEvent event) {
contextMenu.show(cell, event.getScreenX(), event.getScreenY());
}
});
}
ENUM:
public enum Material {
AIR (0, 0.99),
URANIUM (1, 1.12),
LEAD (0, 0.7),
RULEBLOCK (0, 0.99);
double activity;
double reflection;
private Material(double activity, double reflection) {
this.activity = activity;
this.reflection = reflection;
}
double getActivity() {
return activity;
}
public void setActivity(double activity) {
this.activity = activity;
}
double getReflection() {
return reflection;
}
public void setReflection(double reflection) {
this.reflection = reflection;
}
}
The if statement always links to the global variable "radiationvalue" instead of the updated value in the event handler. If I try to access the 'newradiationvalue' in the if statement, I get an error that no such variable can be found (because the one in the Event Handler is not visible from outside).
Maybe someone can tell me how to access the variables in the event handler from outside the event handler?! And if it's not possible: How do I need to change my program to make this work as I want?
Thanks very much in advance!

Why doesn't my number sequence print from the 2d arraylist correctly?

I cannot get the loop to work in the buildDimArray method to store the number combinations "11+11", "11+12", "11+21", "11+22", "12+11", "12+12", "12+21", "12+22", "21+11", "21+12", "21+21", "21+22", "22+11", "22+12", "22+21", and "22+22" into the 2d arraylist with each expression going into one column of the index dimBase-1 row. The loop may work for other people, but for some reason mine isn't functioning correctly. The JVM sees the if dimBase==1 condition, but refuses to check the other conditions. The "WTF" not being printed as a result from the buildDimArray method. If dimBase=1, it prints successfully, but doesn't for the other integers. The dimBase==3 condition needs a loop eventually. The "WTF" is for illustrative purposes. I could get away with a 1d arraylist, but in the future I will likely need the 2d arraylist once the program is completed.
package jordanNumberApp;
import java.util.Scanner;
import java.util.ArrayList;
/*
* Dev Wills
* Purpose: This code contains some methods that aren't developed. This program is supposed to
* store all possible number combinations from numbers 1-dimBase for the math expression
* "##+##" into a 2d arraylist at index row dimBase-1 and the columns storing the
* individual combinations. After storing the values in the arraylist, the print method
* pours the contents in order from the arraylist as string values.
*/
public class JordanNumberSystem {
// a-d are digits, assembled as a math expression, stored in outcomeOutput, outcomeAnswer
public static int dimBase, outcomeAnswer, a, b, c, d;
public static String inputOutcome, outcomeOutput;
public static final int NUM_OF_DIMENSIONS = 9; //Eventually # combinations go up to 9
public static ArrayList<ArrayList<String>> dimBaseArray;
public static Scanner keyboard;
/*
* Constructor for JordanNumber System
* accepts no parameters
*/
public JordanNumberSystem() // Defunct constructor
{
// Declare and Initialize public variables
this.dimBase = dimBase;
this.outcomeOutput = outcomeOutput;
this.outcomeAnswer = outcomeAnswer;
}
// Set all values of variable values
public static void setAllValues()
{
// Initialize
dimBase = 1;
outcomeAnswer = 22; // variables not used for now
outcomeOutput = "1"; // variables not used for now
//a = 1;
//b = 1;
//c = 1;
//d = 1;
dimBaseArray = new ArrayList<ArrayList<String>>();
keyboard = new Scanner(System.in);
}
public static void buildDimArray(int dim)
{
dimBase = dim;
try
{
//create first row
dimBaseArray.add(dimBase-1, new ArrayList<String>());
if( dimBase == 1)
{
a = b = c = d = dimBase ;
dimBaseArray.get(0).add(a+""+b+"+"+c+""+d);
System.out.println("WTF"); // SHOWS
}
else if (dimBase == 2)
{ // dim = 2
a = b = c = d = 1 ;
System.out.println("WTF"); // doesn't show
// dimBaseArray.get(dimBase-1).add(a+""+b+"+"+c+""+d);
for( int i = 1 ; i <= dim ; i++)
a=i;
for( int j = 1 ; j <= dim ; j++)
b=j;
for( int k = 1 ; k <= dim ; k++)
c=k;
for( int l = 1 ; l <= dim ; l++)
{
d=l;
dimBaseArray.get(dim-1).add(a+""+b+"+"+c+""+d);
}
}
else if (dimBase == 3)
{
a = b = c = d = dimBase;
dimBaseArray.get(2).add(a+""+b+"+"+c+""+d);
System.out.println("WTF");
}
}catch (IndexOutOfBoundsException e)
{
System.out.println(e.getMessage());
}
}
public static void printArray(int num) // Prints the contents of the array
{ // Fixing the printing method
try
{
int i = num-1;
for( String string : dimBaseArray.get(i))
{
System.out.println(string);
System.out.println("");
}
} catch (IndexOutOfBoundsException e)
{
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws java.lang.IndexOutOfBoundsException
{
setAllValues(); // sets the initial a,b,c,d values and dimBase, initializes 2d arraylist
// Get the Dimension Base number
System.out.println("Enter Dimension Base Number. Input an integer: ");
int dimBaseInput = keyboard.nextInt(); // Receives integer
dimBase = dimBaseInput;
if( dimBase != 1 && dimBase != 2 && dimBase != 3)
{// Error checking
System.out.println("invalid Dimension Base Number should be 1 or 2 ");
System.exit(1);
}
// Build the arraylist, print, clear, exit
buildDimArray(dimBase);
printArray(dimBase);
dimBaseArray.clear();
System.exit(1);
}
}// End of class

Trouble retrieving random object from "deck" of card objects

My issue is this : When I'm drawing a random card from the deck i've instantiated the returns are sometimes correct(i.e. KING_CLUBS) but sometimes I get a weird one (i.e. SEVEN_). This is odd because when the decks are instantiated, I added a print line statement in the Deck constructor to see if the ID's were being added correctly. Every time without fail the card id's are correct.
The println in Blackjack's hitUser() method was to check the ID of the card being drawn. Sometimes it's correct other times it's not. Can anyone tell me what's happening and why?
Runnable relevant code below
My Card Class:
import java.util.*;
import javax.swing.*;
import java.awt.*;
public class Card {
//cardValues[] represents the tangible values attached to the card faces(ACE, ONE, TWO, THREE, ..., KING)
private final static int cardValues[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
private final static String cardIDs[] = {"ACE_", "TWO_", "THREE_", "FOUR_", "FIVE_", "SIX_", "SEVEN_", "EIGHT_", "NINE_", "TEN_", "JACK_", "QUEEN_", "KING_"};
private int value;
//Name of the card, i.e. "ACE";
private String cardID;
/**
* Constructor
* #param v - card value(I.e. 1 for Ace or 13 for King)
*/
public Card(int v){
setValue(v);
setCardID(v);
}
/**
* Constructor
* #param v - card value(I.e. 1 for Ace or 13 for King)
* #param id - a manually set ID for the card(used for 'illegal' card instantiation)
*/
public Card(int v, String id){
setValue(v);
setCardID(id);
}
/**
* Returns the card ID
* #return - the card ID of the respective card
*/
public String getCardID(){
return cardID;
}
/**
* Returns the card value
* #return - the number value of the respective card
*/
public int getValue(){
return value;
}
/**
* Setter method for card value
* #param v - value
*/
public void setValue(int v){
//Checks to see if v is a valid cardValue
if(v >= 1 && v <= 13){
value = v;
}
}
/**
* 'legal' setter method for card ID
* #param v - number value of the card
*/
public void setCardID(int v){
//Checks to see if v is a valid cardValue
if(v >= 1 && v <= 13){
cardID = cardIDs[v - 1];
}
}
/**
* 'illegal' setter method for card ID
* #param id - String value of the card ID
*/
public void setCardID(String id){
cardID = id;
}
public String getIcon(){
return "blackjack/" + this.getCardID() + ".png";
}
My Deck Class:
import java.util.*;
import javax.swing.*;
import java.awt.*;
public class Deck {
private int numCards;
private String cardSuits[] = {"SPADES", "HEARTS", "DIAMONDS", "CLUBS"};
private static ArrayList<Card> cards = new ArrayList<Card>();
public static JLabel[] cardIcons = new JLabel[52];
public static int dealerHand, playerHand;
/**
* Constructor
*/
public Deck(){
//Will keep track of the index of the 52 cards created
int counter = 0;
for(int y = 0; y < 4; y++){
String suit = cardSuits[y];
for(int z = 1; z < 14; z++){
//Adds a new card and initializes it with its number value
cards.add(new Card(z));
//Replaces the card ID with a new ID containing the card suit (i.e. SPADES)
if(cards.get(counter).getCardID().indexOf("_") == cards.get(counter).getCardID().length() - 1){
String newID = cards.get(counter).getCardID() + suit;
cards.get(counter).setCardID(newID);
System.out.println(newID);
counter++;
} else {
}
}
}
}
/**
* Removes a card from the deck - gets rid of the object in the array of cards once it has been drawn
* #param id - the card to be removed
*/
public void removeCard(String id){
for(int i = 0; i < 52; i++){
if(cards.get(i).getCardID().equalsIgnoreCase(id)){
cards.remove(i);
}
}
}
/**
* Returns the object of the card within a deck
* #param c - the index of the card within the deck
* #return the card object
*/
public Card getCard(int c){
return cards.get(c);
}
/**
* Returns a random card from the array of cards in the deck
* #return - a random card object
*/
public Card getRandomCard(){
Random r = new Random();
int index = r.nextInt(cards.size());
return cards.get(index);
}
/**
* Resets the deck to its original, 'perfect' order
*/
public void reset(){
for(int x = 0; x<cards.size(); x++){
cards.remove(x);
}
//Will keep track of the index of the 52 cards created
int counter = 0;
for(int y = 0; y < 4; y++){
String suit = cardSuits[y];
for(int z = 0; z < 13; z++){
//Adds a new card and initializes it with its number value
cards.add(new Card(z));
//Replaces the card ID with a new ID containing the card suit (i.e. SPADES)
String newID = cards.get(counter).getCardID() + suit;
cards.get(counter).setCardID(newID);
counter++;
}
}
}
My Blackjack Class:
import javax.swing.*;
import net.miginfocom.swing.MigLayout;
/**
* This class provides all of the functionality of the blackjack game
* #author Mohamed Amadou
*
*/
public class Blackjack extends JFrame implements ActionListener{
public MigLayout mig = new MigLayout("insets 0");
public Deck bjDeckHouse = new Deck(), bjDeckUser = new Deck();
public int dealerOffset = 65, userOffset = 65, houseHand = 0,
public final int MAX_BET = 100000;
public JPanel bj = new JPanel(new MigLayout("insets 0")), blackjack = new JPanel(new MigLayout("insets 0"));
public JButton hit;
public Blackjack(){
buildUI();
mig.layoutContainer(bj);
setSize(780, 700);
setResizable(false);
setLayout(mig);
setTitle("Blackjack");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
public void buildUI(){
getContentPane().add(bj);
bj.setBackgroundColor(Color.BLACK);
hit = new JButton("Hit");
hit.addActionListener(this);
bj.add(hit, "pos 570px 285px");
}
public void hitUser(int hand){
JPanel test = new JPanel(new MigLayout("insets 0"));
JFrame testFrame = new JFrame();
testFrame.add(test);
Card hitCard = bjDeckUser.getRandomCard();
hand += hitCard.getValue();
String position = "pos "+ userOffset + "px" + " 580px";
System.out.println(hitCard.getCardID());
bjDeckUser.removeCard(hitCard.getCardID());
turns++;
checkBust(hand);
testFrame.setSize(400, 400);
testFrame.setResizable(false);
testFrame.setLayout(mig);
testFrame.setTitle("Blackjack Rules");
testFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
testFrame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == hit){
hitUser(userHand);
}
}
Your problem lies in reset():
for(int x = 0; x<cards.size(); x++){
cards.remove(x);
}
This actually does not remove all items (just play it through), you should use cards.clear(). Since the deck is then not empty, and you add another 52 cards, the deck will be incorrect. Additionally you will get weird names, probably also SEVEN_CLUBS_SPADES and similar.
Also, your code is a little bit confusing. Suite should be an attribute of a Card, not of a Deck. Cards should be immutable (maybe enums depending on usage). You have 2 initialization code snippets (you should have 1). GUI code in your "business model". Just a few ideas to clean up :)

Libgdx null pointer 2d jump and run game

I want to implement in my 2d jump and run game that my player can shoot but I always get a null pointer exception.
Does anyone know why?
In this class I check for input:
public class InputIngame implements InputProcessor {
Player player;
public void handleInput(){
//control our player using immediate impulses
if (Gdx.input.isKeyJustPressed(Input.Keys.W) && PlayScreen.player.b2body.getLinearVelocity().y == 0)
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(0, 6f), PlayScreen.player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.D) && PlayScreen.player.b2body.getLinearVelocity().x <= 2)
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(0.2f, 0), PlayScreen.player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.A) && PlayScreen.player.b2body.getLinearVelocity().x >= -2)
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(-0.2f, 0), PlayScreen.player.b2body.getWorldCenter(), true);
if (Gdx.input.isKeyPressed(Input.Keys.D) && Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) && PlayScreen.player.b2body.getLinearVelocity().x > 1)
PlayScreen.player.b2body.setLinearVelocity(1, PlayScreen.player.b2body.getLinearVelocity().y);
if (Gdx.input.isKeyPressed(Input.Keys.A) && Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) && PlayScreen.player.b2body.getLinearVelocity().x < -1)
PlayScreen.player.b2body.setLinearVelocity(-1, PlayScreen.player.b2body.getLinearVelocity().y);
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE))
player = new Player();
player.fire();
}
in my screen class I draw the fireball:
#Override
public void render(float delta) {
//separate our update logic from render
update(delta);
//Clear the game screen with Black
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//render our game map
renderer.render();
if (player.isDead == true)
player.die();
player.draw(runner.batch);
//renderer our Box2DDebugLines
b2dr.render(world, gamecam.combined);
runner.batch = new SpriteBatch();
runner.batch.setProjectionMatrix(gamecam.combined);
runner.batch.begin();
player.draw(runner.batch);
runner.batch.end();
if (TimeUtils.timeSinceNanos(startTime) > 1000000000) {
startTime = TimeUtils.nanoTime();
}
Gdx.app.log("FPSLogger", "fps: " + Gdx.graphics.getFramesPerSecond());
}
In my player class I set my variables:
private PlayScreen screen;
private Array<FireBall> fireballs;
And init them:
public Player(PlayScreen screen){
//initialize default values
runner = new HardwareRunner();
this.screen = screen;
fireballs = new Array<FireBall>();
And this method is execudet in the render method:
public void update(float dt){
//update our sprite to correspond with the position of our Box2D body
setPosition(b2body.getPosition().x - getWidth() / 2, b2body.getPosition().y - getHeight() / 2);
//update sprite with the correct frame depending on marios current action
setRegion(getFrame(dt));
for(FireBall ball : fireballs) {
ball.update(dt);
}
}
And there are also these methods:
public void fire(){
fireballs.add(new FireBall(screen, b2body.getPosition().x, b2body.getPosition().y, runningRight ? true : false));
}
public void draw(Batch batch){
super.draw(batch);
for(FireBall ball : fireballs)
ball.draw(batch);
}
And then theres my fireball class:
public class FireBall extends Sprite {
PlayScreen screen;
World world;
Array<TextureRegion> frames;
Animation fireAnimation;
float stateTime;
boolean destroyed;
boolean setToDestroy;
boolean fireRight;
Body b2body;
public FireBall(PlayScreen screen, float x, float y, boolean fireRight){
this.fireRight = fireRight;
this.screen = screen;
this.world = screen.getWorld();
frames = new Array<TextureRegion>();
for(int i = 0; i < 4; i++){
frames.add(new TextureRegion(screen.getAtlas().findRegion("fireball"), i * 8, 0, 8, 8));
}
fireAnimation = new Animation(0.2f, frames);
setRegion(fireAnimation.getKeyFrame(0));
setBounds(x, y, 6 / HardwareRunner.PPM, 6 / HardwareRunner.PPM);
defineFireBall();
}
public void defineFireBall(){
BodyDef bdef = new BodyDef();
bdef.position.set(fireRight ? getX() + 12 /HardwareRunner.PPM : getX() - 12 /HardwareRunner.PPM, getY());
bdef.type = BodyDef.BodyType.DynamicBody;
if(!world.isLocked())
b2body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(3 / HardwareRunner.PPM);
fdef.filter.categoryBits = HardwareRunner.PROJECTILE_BIT;
fdef.filter.maskBits = HardwareRunner.GROUND_BIT |
HardwareRunner.BRICK_BIT |
HardwareRunner.OBJECT_BIT;
fdef.shape = shape;
fdef.restitution = 1;
fdef.friction = 0;
b2body.createFixture(fdef).setUserData(this);
b2body.setLinearVelocity(new Vector2(fireRight ? 2 : -2, 2.5f));
}
public void update(float dt){
stateTime += dt;
setRegion(fireAnimation.getKeyFrame(stateTime, true));
setPosition(b2body.getPosition().x - getWidth() / 2, b2body.getPosition().y - getHeight() / 2);
if((stateTime > 3 || setToDestroy) && !destroyed) {
world.destroyBody(b2body);
destroyed = true;
}
if(b2body.getLinearVelocity().y > 2f)
b2body.setLinearVelocity(b2body.getLinearVelocity().x, 2f);
if((fireRight && b2body.getLinearVelocity().x < 0) || (!fireRight && b2body.getLinearVelocity().x > 0))
setToDestroy();
}
public void setToDestroy(){
setToDestroy = true;
}
public boolean isDestroyed(){
return destroyed;
}
}
But if I try to start the game I get this error:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at de.tobls.hardwarerunner.Input.InputIngame.handleInput(InputIngame.java:30)
at de.tobls.hardwarerunner.Screens.PlayScreen.update(PlayScreen.java:109)
at de.tobls.hardwarerunner.Screens.PlayScreen.render(PlayScreen.java:130)
at com.badlogic.gdx.Game.render(Game.java:46)
at de.tobls.hardwarerunner.HardwareRunner.render(HardwareRunner.java:71)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
line 30 is player.fire();
line 109 is input.handleInput();
line 130 is update(delta);
and line 71 is update(delta); in my main class
I hope anyone can help me!
i think your problem is you forget brakets in "if" condition try this :
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
player = new Player();
player.fire();
}
good luck ;
if any trouble leave a comment ;)