my code is only drawing a straight line no matter how many sides i input in the pSides JTextFields - oop

When I input a digit in the JTextfields it should pass through my actionListener to store all the values (ID, number of sides, length of sides and color) into an arraylist. It should then be used in my polygonContainer class that goes through a for loop and a polygon formula, then prints it out. However what comes out all the time is a straight line.
This is the code i tried:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class ContainerFrame extends JFrame{
ArrayList<PolygonContainer> polygons = new ArrayList<>();
// JTextFields for the number of sides, side length, color, and ID
public JTextField pSides, pSidesLengths, pColor, pID;
// Button for submission
public JButton submitButton;
public void createComponents() {
// Initialize the JTextFields
pSides = new JTextField();
pSidesLengths = new JTextField();
pColor = new JTextField();
pID = new JTextField();
submitButton = new JButton("Submit");
submitButton.addActionListener(new ContainerButtonHandler(this));
JPanel textFieldsPanel = new JPanel();
// uses a gridlayout to organise the textfields then sets it as north
textFieldsPanel.setLayout(new GridLayout(5, 2));
textFieldsPanel.add(new JLabel("Sides:"));
textFieldsPanel.add(pSides);
textFieldsPanel.add(new JLabel("Sides Length:"));
textFieldsPanel.add(pSidesLengths);
textFieldsPanel.add(new JLabel("Color:"));
textFieldsPanel.add(pColor);
textFieldsPanel.add(new JLabel("ID:"));
textFieldsPanel.add(pID);
add(textFieldsPanel, BorderLayout.NORTH);
add(submitButton, BorderLayout.SOUTH);
JPanel drawPanel = new ContainerPanel(this);
add(drawPanel, BorderLayout.CENTER);
setSize(1600, 900);
setVisible(true);
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); // Close action.
}
public static void main(String[] args) {
ContainerFrame cFrame = new ContainerFrame();
cFrame.createComponents();
}
}
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
class ContainerButtonHandler implements ActionListener {
ContainerFrame theApp; // Reference to ContainerFrame object
// ButtonHandler constructor
ContainerButtonHandler(ContainerFrame app) {
theApp = app;
}
public void actionPerformed(ActionEvent e) {
// Get the text from the JTextFields using the getText method
String sides = theApp.pSides.getText();
String sidesLengths = theApp.pSidesLengths.getText();
String id = theApp.pID.getText();
//parse the values as integers
int intSides = Integer.parseInt(sides);
int intSidesLength = Integer.parseInt(sidesLengths);
int intId = Integer.parseInt(id);
//does the input validation where sides, sides length and id needs to be positive integers
if (intId >= 100000 && intId <= 999999 && intSides >= 0 && intSidesLength >= 0) {
// The inputs are valid
String color = theApp.pColor.getText();
// Store the values in an arraylist or other data structure
ArrayList<String> polygonArray = new ArrayList<String>();
polygonArray.add(sides);
polygonArray.add(sidesLengths);
polygonArray.add(color);
polygonArray.add(id);
PolygonContainer polygon = new PolygonContainer(polygonArray);
theApp.polygons.add(polygon);
theApp.repaint();
JOptionPane.showMessageDialog(theApp, "Polygon" + id + "was added to the list.", "Success", JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(theApp, "The Polygon" + id + "was not added to the list as a valid Id was not provided.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class PolygonContainer implements Comparable<PolygonContainer>{
Color pColor = Color.BLACK; // Colour of the polygon, set to a Colour object, default set to black
int pId = 000000; // Polygon ID should be a six digit non-negative integer
int pSides; // Number of sides of the polygon, should be non-negative value
int pSideLengths; // Length of each side in pixels of the polygon, should be non-negative value
int polyCenX; // x value of centre point (pixel) of polygon when drawn on the panel
int polyCenY; // y value of centre point (pixel of polygon when drawn on the panel
int [] pointsX; // int array containing x values of each vertex (corner point) of the polygon
int [] pointsY; // int array containing y values of each vertex (corner point) of the polygon
// Constructor currently set the number of sides and the equal length of each side of the Polygon
//Constructor that takes the values from the array
public PolygonContainer(ArrayList<String> values){
this.pSides = Integer.parseInt(values.get(0));
this.pSideLengths = Integer.parseInt(values.get(1));
this.pColor = Color.getColor(values.get(2));
this.pId = Integer.parseInt(values.get(3));
pointsX = new int[pSides];
pointsY = new int[pSides];
}
// Used to populate the points array with the vertices corners (points) and construct a polygon with the
// number of sides defined by pSides and the length of each side defined by pSideLength.
// Dimension object that is passed in as an argument is used to get the width and height of the ContainerPanel
// and used to determine the x and y values of its centre point that will be used to position the drawn Polygon.
public Polygon getPolygonPoints(Dimension dim) {
polyCenX = dim.width / 2; // x value of centre point of the polygon
polyCenY = dim.height / 2; // y value of centre point of the polygon
Polygon p = new Polygon();
for (int i = 0; i < pSides; i++) {
// Calculate the x and y coordinates of the ith point of the polygon
int x = polyCenX + pSideLengths * (int) Math.cos(2.0 * Math.PI * i / pSides);
int y = polyCenY + pSideLengths * (int) Math.sin(2.0 * Math.PI * i / pSides);
// Add the x and y coordinates to the pointsX and pointsY arrays
pointsX[i] = x;
pointsY[i] = y;
// Add the point to the polygon object using the addPoint method
p.addPoint(x, y);
}
return p;
}
// You will need to modify this method to set the colour of the Polygon to be drawn
// Remember that Graphics2D has a setColor() method available for this purpose
public void drawPolygon(Graphics2D g, Dimension d) {
//Set color of polygon
g.setColor(pColor);
Polygon p = getPolygonPoints(d);
g.draw(p);
//this creates a bounding box around the polygon
Rectangle2D bounds = p.getBounds2D();
g.draw(bounds);
}
// gets a stored ID
public int getID() {
return pId;
}
#Override
// method used for comparing PolygonContainer objects based on stored ids, you need to complete the method
public int compareTo(PolygonContainer o) {
return 0;
}
// outputs a string representation of the PolygonContainer object, you need to complete this to use for testing
public String toString()
{
return "";
}
}
import javax.swing.JPanel;
import java.awt.*;
public class ContainerPanel extends JPanel{
ContainerFrame conFrame;
public ContainerPanel(ContainerFrame cf) {
conFrame = cf; // reference to ContainerFrame object
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D comp = (Graphics2D)g; // You will need to use a Graphics2D objects for this
Dimension size = getSize(); // You will need to use this Dimension object to get
// the width / height of the JPanel in which the
// Polygon is going to be drawn
for (PolygonContainer polygon : conFrame.polygons) {
polygon.drawPolygon(comp, size);
}
}
}
JFrame

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

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 :)

arrayList i only show the last element

I have the following problem. I'm trying to show all the elements of a display arrayList but I can only see the last item repeated as many times as there are number of elements in the ArrayList.
import java.util.ArrayList;
import java.util.Iterator;
public class PurebaArrayList {
public static void main(String[] args) {
ArrayList<PuntoDouble> puntos = new ArrayList<>();
PuntoDouble p = new PuntoDouble();
for(int cont = 0; cont< 100; cont++){
p.setX(cont);
p.setY(cont);
puntos.add(p);
}
System.out.println(puntos.toString());
}
}
public class PuntoDouble{
private double x;
private double y;
public PuntoDouble(double x, double y) {
this.x = x;
this.y = y;
}
public PuntoDouble(){
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
#Override
public String toString() {
return "PuntoDouble{" + "x=" + x + ", y=" + y + '}';
}
}
Thanks
You need to create a new PuntoDouble for every entry you add to the list. At the moment you add just a single instance of a PuntoDouble which you modify.
Therefore change the code to:
for(int cont = 0; cont< 100; cont++){
PuntoDouble p = new PuntoDouble();
p.setX(cont);
p.setY(cont);
puntos.add(p);
}
You are, literally, adding the same PuntoDouble as each of the 100 elements of the array. If you want them to be distinct from each other, you need to make a new one for each.
For debugging,slightly change 100 to 3 and add for each iteration to print out the elements in puntos.
// adds to ArrayList
for(int cont = 0; cont< 10; cont++){
p.setX(cont);
p.setY(cont);
System.out.println("[add]" + p);
puntos.add(p);
}
// iterates ArrayList puntos' elements
for(PuntoDouble pd : puntos){
System.out.println("[contain]" + pd);
}
debug output lines:
[add]PuntoDouble{x=0.0, y=0.0}
[add]PuntoDouble{x=1.0, y=1.0}
[add]PuntoDouble{x=2.0, y=2.0}
[add]PuntoDouble{x=3.0, y= 3.0}
[contain]PuntoDouble{x=9.0, y=9.0}
[contain]PuntoDouble{x=9.0, y=9.0}
[contain]PuntoDouble{x=9.0, y=9.0}
What you did is created an PuntoDouble object p and initilized it by invoking default constructor. In the for loop, the values of p modifies, but the reference of p never changed, therefore you kept adding the same object into ArrayList 100 times, all of those added objects refer to the same address in memory(new an object once before the for loop) which the value x is 99.0 and y is 99.0 (the last added values)
What you should do is creating a new object each iterate.
for(int cont = 0; cont< 100; cont++){
puntos.add(new PuntoDouble(cont, cont));
}

My current GPS Position under Nutiteq is not properly updated

as basis for my GPS functionality I've taken HelloMap3D Example of Nutiteq (Thx Jaak) and I adapted to show my current GPS position light different of this example, so, no growing yelow circles but a fix blue translucent circle with a center point as my current Position and works fine except the update. It should erase the past position if location is changed, so that
this update happens as in the example in the method onLocationChanged
This is the code in my Main Activity
protected void initGps(final MyLocationCircle locationCircle) {
final Projection proj = mapView.getLayers().getBaseLayer().getProjection();
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
locationCircle.setLocation(proj, location);
locationCircle.setVisible(true);
}
// Another Methods...
}
}
I have adapted MyLocationCircle Class like this
public void update() {
//Draw center with a drawable
Bitmap bitmapPosition = BitmapFactory.decodeResource(activity.getResources(), R.drawable.ic_home);
PointStyle pointStyle = PointStyle.builder().setBitmap(bitmapPosition).setColor(Color.BLUE).build();
// Create/update Point
if ( point == null ) {
point = new Point(circlePos, null, pointStyle, null);
layer.add(point);
} else { // We just have to change the Position to actual Position
point.setMapPos(circlePos);
}
point.setVisible(visible);
// Build closed circle
circleVerts.clear();
for (float tsj = 0; tsj <= 360; tsj += 360 / NR_OF_CIRCLE_VERTS) {
MapPos mapPos = new MapPos(circleScale * Math.cos(tsj * Const.DEG_TO_RAD) + circlePos.x, circleScale * Math.sin(tsj * Const.DEG_TO_RAD) + circlePos.y);
circleVerts.add(mapPos);
}
// Create/update line
if (circle == null) {
LineStyle lineStyle = LineStyle.builder().setWidth(0.05f).setColor(Color.BLUE).build();
PolygonStyle polygonStyle = PolygonStyle.builder().setColor(Color.BLUE & 0x80FFFFFF).setLineStyle(lineStyle).build();//0xE0FFFF
circle = new Polygon(circleVerts, null, polygonStyle, circle_data);
layer.add(circle);
} else {
circle.setVertexList(circleVerts);
}
circle.setVisible(visible);
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public void setLocation(Projection proj, Location location) {
circlePos = proj.fromWgs84(location.getLongitude(), location.getLatitude());
projectionScale = (float) proj.getBounds().getWidth();
circleRadius = location.getAccuracy();
// Here is the most important modification
update();
}
So, each time our Position changes is called onLocationChanged(Location location) Method and there will be called locationCircle.setLocation(location) and last there, it will be called update called.
The questions are, What am I making wrong? and How can I solve it?
Thank you in advance.
You create and add new circle with every update. You should reuse single one, just update vertexes with setVertexList(). In particular this line should be outside onLocationChanged cycle, somewhere in initGPS perhaps:
circle = new Polygon(circleVerts, null, polygonStyle, circle_data);

in libgdx, how to create dynamic texture?

In libgdx, how to create dynamic texture? e.g: create hill or mountain?like the Game
Thank you for your answer, i am waitting for your reply.
Example
=======
package com.badlogic.gdx.tests.bullet;
/**
Question: In libgdx, how to create dynamic texture?
Answer : Use a private render function to draw in a private frame buffer
convert the frame bufder to Pixmap, create Texture.
Author : Jon Goodwin
**/
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Pixmap;
...//(ctrl-shift-o) to auto-load imports in Eclipse
public class BaseBulletTest extends BulletTest
{
//class variables
=================
public Texture texture = null;//create this
public Array<Disposable> disposables = new Array<Disposable>();
public Pixmap pm = null;
//---------------------------
#Override
public void create ()
{
init();
}
//---------------------------
public static void init ()
{
if(texture == null) texture(Color.BLUE, Color.WHITE);
TextureAttribute ta_tex = TextureAttribute.createDiffuse(texture);
final Material material_box = new Material(ta_tex, ColorAttribute.createSpecular(1, 1, 1, 1),
FloatAttribute.createShininess(8f));
final long attributes1 = Usage.Position | Usage.Normal | Usage.TextureCoordinates;
final Model boxModel = modelBuilder.createBox(1f, 1f, 1f, material_box, attributes1);
...
}
//---------------------------
public Texture texture(Color fg_color, Color bg_color)
{
Pixmap pm = render( fg_color, bg_color );
texture = new Texture(pm);//***here's your new dynamic texture***
disposables.add(texture);//store the texture
}
//---------------------------
public Pixmap render(Color fg_color, Color bg_color)
{
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
SpriteBatch spriteBatch = new SpriteBatch();
m_fbo = new FrameBuffer(Format.RGB565, (int)(width * m_fboScaler), (int)(height * m_fboScaler), false);
m_fbo.begin();
Gdx.gl.glClearColor(bg_color.r, bg_color.g, bg_color.b, bg_color.a);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Matrix4 normalProjection = new Matrix4().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.setProjectionMatrix(normalProjection);
spriteBatch.begin();
spriteBatch.setColor(fg_color);
//do some drawing ***here's where you draw your dynamic texture***
...
spriteBatch.end();//finish write to buffer
pm = ScreenUtils.getFrameBufferPixmap(0, 0, (int) width, (int) height);//write frame buffer to Pixmap
m_fbo.end();
// pm.dispose();
// flipped.dispose();
// tx.dispose();
m_fbo.dispose();
m_fbo = null;
spriteBatch.dispose();
// return texture;
return pm;
}
//---------------------------
}//class BaseBulletTest
//---------------------------