Health + Shield bar - java

So i'm trying to make a health + shield bar in my game. If you have ever played League of Legends or Heroes of the Storm, i'm trying to create a health and shield bar that works like that. if not, I have some images for you:
(stackoverflow will not let me post more than 2 links, so just imagine a full health bar :) )
The first example is just the normal health bar displaying health. I got this to work fine by multiplying the percentage health (health/maxHealth) and multiplying that number by the length of the health bar (51)
This second example shows how the health and shield should look when the player is at full health. This is working fine too.
My problem comes here, when the player is not at full health. as you can see, in the first picture, Kalista has around 550 health. Then as she gains the shield, her health bar goes to around 850 total and the 300 health shield is grey. Then once she's taken damage to around 300 health, the 300 health shield is no longer compressed like when it was in the 850 health. My HUD health bar works until this point. Even when the health bar is not at its full capacity, it tries to compress the shield and health into what just the health bar was.
Here's my current code:
package net.masterzach32.sidescroller.assets.gfx;
import java.awt.*;
import java.awt.image.BufferedImage;
import net.masterzach32.sidescroller.assets.Assets;
import net.masterzach32.sidescroller.entity.EntityPlayer;
import net.masterzach32.sidescroller.util.LogHelper;
public class HUD {
private EntityPlayer player;
private BufferedImage image;
private Font font;
double b0 = 31, b1 = 20, hx = 31, mx = 20;
public HUD(EntityPlayer p) {
player = p;
try {
image = Assets.getImageAsset("hud");
font = new Font("Arial", Font.PLAIN, 14);
}
catch(Exception e) {
e.printStackTrace();
}
}
public void render(Graphics2D g) {
g.drawImage(image, 0, 15, null);
double h0 = player.getHealth() / player.getMaxHealth();
double h1 = h0 * hx;
double m0 = player.getShield() / player.getMaxShield();
double m1 = m0 * mx;
if((int) (h1 + m1) <= hx + mx) {
int f = (int) (mx - m1);
h1 += f;
}
LogHelper.logInfo("" + (int) (h1 + m1));
if(h1 >= b0) b0 = h1;
if(h1 < b0) b0 -= .7;
if(m1 >= b1) b1 = m1;
if(m1 < b1) b1 -= .7;
// health bar
g.setColor(new Color(200, 0, 0));
g.fillRect(17, 18, (int) b0, 13);
g.setColor(new Color(0, 170, 0));
g.fillRect(17, 18, (int) h1, 13);
// mana bar
g.setColor(new Color(200, 0, 0));
g.fillRect((int) (17 + b0), 18, (int) b1, 13);
g.setColor(Color.BLUE);
g.fillRect((int) (17 + h1), 18, (int) m1, 13);
g.setFont(font);
g.setColor(Color.WHITE);
if(player.getOrbCurrentCd() > 0) g.drawString("" + (player.getOrbCurrentCd() / 60 + 1), 0, 12);
else g.drawString("" + (player.getOrbCurrentCd() / 60), 0, 12);
g.drawString(player.getLevel() + " - " + (int) player.getExp() + "/" + (int) player.getMaxExp(), 1, 70);
g.setFont(font);
g.drawString((int) (player.getHealth()) + "/" + (int) (player.getMaxHealth()), 16, 29);
}
}

Related

How to do random generation of barriers for car collision game

How do I create a random car barrier for my game? I have this top-down car game that I need to make. This game aims to make the car move up and down (on the y-axis) to avoid the barriers, while the barriers are moving toward the car (on the x-axis). Is it possible to create a random generation of the barriers when they spawn, making the game enjoyable? Right now, I only have a set of barriers that last for 12 seconds before I get easily through them. Can I also keep the spacing of the barriers the same? So the car can fit.
code
color green = color(0,195,0);
color red = color(195,0,0);
color grey = color(100,100,100);
color yellow = color(200,200,0);
color white = color(255,255,255);
float roadx = 70, road1y = 130;
float road2y = 230, road3y = 330;
float carY = road2y;
float carX = roadx;
float carUPspeed = 1;
float laneX = 700;
float lanes;
void lane1(float x, float y){
fill(white);
rect(x + 100, y,30,100);
rect(x + 250, y + 100,30,100);
rect(x + 250, y + 200, 30, 100);
rect(x + 400, y + 100, 30, 100);
rect(x + 550, y + 100, 30, 100);
rect(x + 550, y, 30, 100);
rect(x + 700, y + 100, 30, 100);
rect(x + 700, y + 200, 30, 100);
}
void background(){
background(green);
}
void car(){
fill(red);
rect(carX, carY, 60, 40);
}
void setup(){
surface.setTitle("dodge");
size(900, 500);
}
void draw(){
background();
noStroke();
fill(grey);
rect(roadx - 400, road1y - 30, 1500, 100);
stroke(yellow);
strokeWeight(5);
rect(roadx - 400, road2y - 30, 1500, 100);
noStroke();
rect(roadx - 400, road3y - 27, 1500, 100);
car();
lane1(laneX, 100);
laneX -= 1;
lanes = 1;
}
void keyPressed(KeyEvent event){
if (key == 'w'){
if(carY != 130){
carY = carY - 100;
}
}
if (key == 's'){
if(carY != 330){
carY = carY + 100;
}
}
}
I've modified your lane rendering and added dynamic creation of barriers. Every 150 pixels moved, the barriers are updated (leftmost barriers are removed, new ones are added at the rightmost position and the cycle starts over).
The barriers are stored as an integer between 0 and 6, as there are 7 possibilities for the barrier positions:
int | 0 1 2 3 4 5 6
------+--------------------
lane0 | # # #
lane1 | # # #
lane2 | # # #
Hope this helps.
Modified code:
import java.util.*;
private static final int SCREEN_X = 900;
private static final int SCREEN_Y = 500;
private static final int LANE_HEIGHT = 100;
private static final int BARRIER_DISTANCE = 150;
private static final int BARRIER_HEIGHT = 100;
private static final int BARRIER_WIDTH = 30;
color green = color(0,195,0);
color red = color(195,0,0);
color grey = color(100,100,100);
color yellow = color(200,200,0);
color white = color(255,255,255);
float roadx = 70, road1y = 130;
float road2y = 230, road3y = 330;
float carY = road2y;
float carX = roadx;
float carUPspeed = 1;
float laneX = 50;
float lanes;
List<Integer> barriers;
void lane1(float x){
fill(white);
for (Integer b : barriers)
{
switch(b)
{
case 0: // ___
break;
case 1: // X__
rect(x, LANE_HEIGHT, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 2: // _X_
rect(x, LANE_HEIGHT * 2, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 3: // __X
rect(x, LANE_HEIGHT * 3, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 4: // _XX
rect(x, LANE_HEIGHT * 2, BARRIER_WIDTH, BARRIER_HEIGHT);
rect(x, LANE_HEIGHT * 3, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 5: // XX_
rect(x, LANE_HEIGHT * 1, BARRIER_WIDTH, BARRIER_HEIGHT);
rect(x, LANE_HEIGHT * 2, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 6: // X_X
rect(x, LANE_HEIGHT * 1, BARRIER_WIDTH, BARRIER_HEIGHT);
rect(x, LANE_HEIGHT * 3, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
}
x += BARRIER_DISTANCE;
}
}
void background(){
background(green);
}
void car(){
fill(red);
rect(carX, carY, 60, 40);
}
void setup(){
surface.setTitle("dodge");
size(900, 500);
// Initially generate 7 barriers (one more than the screen can fit)
barriers = new ArrayList<Integer>();
for (int i = 0; i <= (SCREEN_X / BARRIER_DISTANCE); i++)
{
barriers.add(int(random(0, 6)));
}
// Set the first to barriers to 'no barrier' to the player initially has some time
barriers.set(0, 0);
barriers.set(1, 0);
}
void draw(){
background();
noStroke();
fill(grey);
rect(roadx - 400, road1y - 30, 1500, LANE_HEIGHT);
stroke(yellow);
strokeWeight(5);
rect(roadx - 400, road2y - 30, 1500, LANE_HEIGHT);
noStroke();
rect(roadx - 400, road3y - 27, 1500, LANE_HEIGHT);
car();
lane1(laneX);
laneX -= 1;
// laneX cycles from 50 to -100 (because of draw position)
// So, every 150 pixels moved
if (laneX == -100)
{
// Reset laneX
laneX = 50;
// Remove leftmost barrier
barriers.remove(0);
// Add new barriers, incoming from the right
barriers.add(int(random(0, 6)));
}
lanes = 1;
}
void keyPressed(KeyEvent event){
if (key == 'w'){
if(carY != 130){
carY = carY - 100;
}
}
if (key == 's'){
if(carY != 330){
carY = carY + 100;
}
}
}

Pieces not being removed when taken

I am creating a Chess Game and I just finished the basic Ai, but whenever a piece is taken it disappears and comes back a few turns later. The piece shouldn't even be in the list that renders the pieces.
This is the class that render/adds/sets the new pieces
setPieceLoc() sets the old piece at its new location and removes both the original and the newLoc from all lists.
Does anyone see why this is happening? There is no other class that adds new information to the lists, so as far as I can tell it must be an error here.
package me.xthegamerplayz.FirstGame.board;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import me.xthegamerplayz.FirstGame.board.tiles.ChessImages;
import me.xthegamerplayz.FirstGame.rules.LegalMoves;
public class Board {
public static void addPiece(int x, int y, int piece) {
Point point = new Point();
point.setLocation(x, y);
if(piece > 16)
ChessBoard.black.put(point, piece);
else
ChessBoard.white.put(point, piece);
}
public static void setPieceLoc(Point original, Point newLoc) {
int piece = 8;
if(ChessBoard.white.containsKey(original))
piece = ChessBoard.white.get(original);
else if(ChessBoard.black.containsKey(original))
piece = ChessBoard.black.get(original);
//Remove piece at newLoc
if(ChessBoard.white.containsKey(newLoc))
ChessBoard.white.remove(newLoc);
else if(ChessBoard.black.containsKey(newLoc))
ChessBoard.black.remove(newLoc);
//Remove piece from previous location
if(ChessBoard.white.containsKey(original))
ChessBoard.white.remove(original);
else if(ChessBoard.black.containsKey(original))
ChessBoard.black.remove(original);
if(piece > 16)
ChessBoard.black.put(newLoc, piece);
else
ChessBoard.white.put(newLoc, piece);
}
public void registerPieces() {
//Pawns
for(int x = 0; x < 8; x++) {
addPiece(x, 1, 8);
addPiece(x, 6, 24);
}
//White
addPiece(0, 0, 9);
addPiece(1, 0, 10);
addPiece(2, 0, 11);
addPiece(5, 0, 11);
addPiece(6, 0, 10);
addPiece(7, 0, 9);
addPiece(4, 0, 12);
addPiece(3, 0, 13);
//Black
addPiece(0, 7, 25);
addPiece(1, 7, 26);
addPiece(2, 7, 27);
addPiece(5, 7, 27);
addPiece(6, 7, 26);
addPiece(7, 7, 25);
addPiece(3, 7, 28);
addPiece(4, 7, 29);
}
public void render(Graphics g) {
for(Point point : ChessBoard.white.keySet()) {
int piece = ChessBoard.white.get(new Point(point));
int x = (int) (point.getX()*64) + 20;
int y = (int) (point.getY()*64) + 20;
boolean showTiles = false;
if(showTiles) {
if(piece == 24) {
LegalMoves lm = new LegalMoves(point);
for(Point p : lm.moves()) {
int bx = (int) (p.getX()*64) + 20;
int by = (int) (p.getY()*64) + 20;
g.setColor(Color.green);
g.fillRect(bx, by, 64, 64);
}
}
}
g.drawImage(ChessImages.getPieceImage(piece), x, y, null);
}
for(Point point : ChessBoard.black.keySet()) {
int piece = ChessBoard.black.get(new Point(point));
int x = (int) (point.getX()*64) + 20;
int y = (int) (point.getY()*64) + 20;
boolean showTiles = false;
if(showTiles) {
if(piece == 24) {
LegalMoves lm = new LegalMoves(point);
for(Point p : lm.moves()) {
int bx = (int) (p.getX()*64) + 20;
int by = (int) (p.getY()*64) + 20;
g.setColor(Color.green);
g.fillRect(bx, by, 64, 64);
}
}
}
g.drawImage(ChessImages.getPieceImage(piece), x, y, null);
}
}
}
It looks like you are attempting to make a move a piece from somewhere that is empty.
Note that, when your original is in neither the black nor white maps, it will use piece 8, which appears to be a white pawn. That happens to be the piece reappearing in your video.
You should really be throwing an exception when this happens, because moving a piece from an empty square makes no sense. Doing this should help you debug the circumstance in which this is happening:
if(ChessBoard.white.containsKey(original))
piece = ChessBoard.white.get(original);
else if(ChessBoard.black.containsKey(original))
piece = ChessBoard.black.get(original);
else
throw new IllegalArgumentException("Attempting to move piece from empty square " + original);

Set an analog clock with an initial time using Java

For my programming class I'm working on a clock. The clock has to be set at an initial time, which I cannot figure out how to do. The clock I'm currently working with just uses the system time. I've tried setting a time using cal.set but then it just freezes on what I want to be the initial time and time doesn't progress. How can I edit this to allow me to have a set initial time, but have the clock still work?
package Clock;
package Clock;
import java.applet.Applet;
import java.awt.Color;
import java.lang.Object;
import javax.swing.JPanel;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JFrame;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Component extends Applet implements Runnable {
private static final long serialVersionUID = 1L;
public static String name = "My Clock";
public static int size = 600;
public static boolean isRunning = false;
public static Graphics g;
public static Image screen;
public Numbers number;
public static JFrame frame;
public static void main(String [] args) {
Component component = new Component();
frame = new JFrame();
frame.add(component);
frame.setSize(size+6, size + 28);
frame.setTitle(name);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
component.start();
}
public void start() {
requestFocus();
number = new Numbers();
isRunning = true;
Thread th = new Thread(this);
th.start();
}
public void run() {
screen = createVolatileImage(size, size);
while (isRunning) {
tick();
render(g);
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void tick() {
}
public double time;
public int anim;
public int anim2;
public int anim3;
public int anim4;
public int center = size/2;
public int radius = (size-40)/2;
public void render(Graphics g) {
// Drawing to image
screen = createImage(size, size);
g = screen.getGraphics();
//Drawing the background
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, size, size);
// Drawing the frame(outside circle)
g.setColor(Color.black);
g.fillOval(5, 5, size - 10, size - 10);
g.setColor(Color.white);
//g.setColor(new Color(new Random().nextInt(255). new Random().nextInt(255), new Random().nextInt(255)));
//g.drawOval(10, 10, size - 20, size - 20);
g.fillOval(20, 20, size - 40, size - 40);
number.render(g);
// Math and Drawing for Lines
for (int i = 0; i < 60; i++) {
radius = size - 40;
anim = center + (int) ((Math.sin(i % 60.0 / 60 * Math.PI * 2) * (radius / 2)));
anim2 = center - (int) ((Math.cos(i % 60.0 / 60 * Math.PI * 2) * (radius / 2)));
radius = size - 60;
anim3 = center + (int) ((Math.sin(i % 60.0 / 60 * Math.PI * 2) * (radius / 2)));
anim4 = center - (int) ((Math.cos(i % 60.0 / 60 * Math.PI * 2) * (radius / 2)));
g.drawLine(anim, anim2, anim3, anim4);
}
// Math for hour hand
radius = size - 140;
// time = System.currentTimeMillis() % 3600000 / 3600000 * Math.PI;
int t = (int) (System.currentTimeMillis() + 17300000) + 3600000+ 3600000 + 3600000 + 3600000 + 3600000 + 3600000 + 3600000 + 3600000;
anim = center
+ (int) ((Math.sin(t % 43200000.0
/ 43200000 * Math.PI * 2) * (radius / 2))) + 7;
anim2 = center
- (int) ((Math.cos(t % 43200000.0
/ 43200000 * Math.PI * 2) * (radius / 2))) + 7;
// Drawing the hour hand
g.setColor(Color.black);
g.fillOval(center - 8, center - 8, 16, 16);
g.drawLine(center, center, anim, anim2);
g.drawLine(center + 1, center, anim + 1, anim2);
g.drawLine(center, center + 1, anim, anim2 + 1);
g.drawLine(center - 1, center, anim - 1, anim2);
g.drawLine(center, center - 1, anim, anim2 - 1);
g.drawLine(center + 1, center + 1, anim, anim2);
g.drawLine(center + 1, center - 1, anim, anim2);
g.drawLine(center - 1, center + 1, anim, anim2);
g.drawLine(center - 1, center - 1, anim, anim2);
// Math for minute hand
radius = size - 90;
// time = System.currentTimeMillis() % 3600000 / 3600000 * Math.PI;
anim = center
+ (int) ((Math.sin(System.currentTimeMillis() % 3600000.0
/ 3600000 * Math.PI * 2) * radius / 2));
anim2 = center
- (int) ((Math.cos(System.currentTimeMillis() % 3600000.0
/ 3600000 * Math.PI * 2) * radius / 2));
// Drawing the minute hand
g.setColor(Color.black);
g.drawLine(center, center, anim, anim2);
g.drawLine(center + 1, center, anim + 1, anim2);
g.drawLine(center, center + 1, anim, anim2 + 1);
g.drawLine(center - 1, center, anim - 1, anim2);
g.drawLine(center, center - 1, anim, anim2 - 1);
//Math for second hand
DateFormat dateFormat = new SimpleDateFormat("ss");
Calendar cal = Calendar.getInstance();
String s = dateFormat.format(cal.getTime());
radius = size - 70;
// time = System.currentTimeMillis() % 60000 / 60000 * Math.PI;
anim = center
+ (int) ((Math.sin(Integer.parseInt(s) % 60.0 / 60 * Math.PI
* 2) * (radius / 2)));
anim2 = center
- (int) ((Math.cos(Integer.parseInt(s) % 60.0 / 60 * Math.PI
* 2) * (radius / 2)));
// Drawing the second hand
g.setColor(Color.red);
g.drawLine(center, center, anim, anim2);
g.drawLine(center + 1, center, anim + 1, anim2);
g.drawLine(center, center + 1, anim, anim2 + 1);
g.drawLine(center - 1, center, anim - 1, anim2);
g.drawLine(center, center - 1, anim, anim2 - 1);
// Center circle
g.fillOval(center - 5, center - 5, 10, 10);
g.setColor(Color.black);
g.fillOval(center - 2, center - 2, 4, 4);
// g.setColor(new Color(new Random().nextInt(255), new Random().nextInt(255), new Random().nextInt(255)));
// g.fillRect(0, 0, getWidth(), getHeight());
// Drawing to screen
g = getGraphics();
g.drawImage(screen, 0, 0, size, size, this);
g.dispose();
}
}
and
package Clock;
import java.applet.Applet;
import java.awt.Color;
import java.lang.Object;
import javax.swing.JPanel;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JFrame;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Numbers extends JPanel {
private static final long serialVersionUID=1L;
public int size = Component.size;
public int center = size/2;
public void setFont(Font font) {
super.setFont(font);
repaint();
}
public String getDay() {
DateFormat dateFormat=new SimpleDateFormat("dd");
Calendar cal = Calendar.getInstance();
String s = dateFormat.format(cal.getTime());
int day = Integer.parseInt(s);
String d = day + "";
// sets ordinal indicator
switch(day) {
case 1:
case 21:
case 31:
d += "st";
break;
case 2:
case 22:
d += "nd";
break;
case 3:
case 23:
d += "rd";
break;
default:
d += "th";
}
return d;
}
public String getHour() {
DateFormat dateFormat = new SimpleDateFormat("HH");
Calendar cal = Calendar.getInstance();
String s = dateFormat.format(cal.getTime());
int hour = Integer.parseInt(s) -1;
String n = hour + "";
if(hour < 10) {
n=hour+"";
}
return n;
}
public String getMonth() {
DateFormat dateFormat = new SimpleDateFormat("MM");
Calendar cal = Calendar.getInstance();
String s = dateFormat.format(cal.getTime());
int month = Integer.parseInt(s);
// sets month name to number
String m = "";
switch (month)
{
case 1:
m= "January";
break;
case 2:
m= "February";
break;
case 3:
m= "March";
break;
case 4:
m= "April";
break;
case 5:
m= "May";
break;
case 6:
m= "June";
break;
case 7:
m= "July";
break;
case 8:
m= "August";
break;
case 9:
m= "September";
break;
case 10:
m= "October";
break;
case 11:
m= "November";
break;
case 12:
m= "December";
}
return m;
}
public void render(Graphics g) {
g.setColor(Color.black);
DateFormat dateFormat = new SimpleDateFormat(":mm:ss");
Calendar cal = Calendar.getInstance();
String s = dateFormat.format(cal.getTime());
int n = center - ((s.length() *13)/2);
//265
g.setFont(new Font("Arial", 1, 20));
s = (Integer.parseInt(getHour(), 10) % 12 + 1) + "" + dateFormat.format(cal.getTime());
n = center - (s.length() * 10 / 2);
g.setColor(Color.DARK_GRAY);
g.fillRoundRect(250, 348, 100, 30, 6, 6);
g.setColor(Color.LIGHT_GRAY);
g.fillRoundRect(252, 350, 96, 26, 6, 6);
g.setColor(Color.BLACK);
g.drawString("TIME", 275, 345);
g.drawString("DATE", 275, 225);
g.drawString("AM", 255, 150);
g.drawString("PM", 315, 150);
g.drawString(s, n, 370);
int p = Integer.parseInt(getHour(), 10);
if(p < 11 || p == 24) {
g.fillOval(265, 160, 10, 10);
g.drawOval(325, 160, 10, 10);
} else {
g.drawOval(265, 160, 10, 10);
g.fillOval(325, 160, 10, 10);
}
dateFormat = new SimpleDateFormat("yyyy");
cal = Calendar.getInstance();
s = getMonth() + " " + getDay() + ", " + dateFormat.format(cal.getTime());
n = center - (int) ((s.length() * 10.25) / 2);
g.setColor(Color.DARK_GRAY);
g.fillRoundRect(200, 228, 200, 30, 6, 6);
g.setColor(Color.LIGHT_GRAY);
g.fillRoundRect(202, 230, 196, 26, 6, 6);
g.setColor(Color.BLACK);
g.drawString(s, n, 250);
s = Component.name;
n=center - (int)((s.length()*10)/2);
g.drawString(s, n , 450);
g.setFont(new Font("Arial", 1, 30));
int radius = size - 100;
for(int i = 0; i < 12; i++) {
double anim = (int) ((Math.sin((i+1) % 12.0 / 12 * Math.PI * 2) * (radius / 2)));
double anim2 = (int) ((Math.cos((i+1) % 12.0 / 12 * Math.PI * 2) * (radius / 2)));
if(i >= 9){
anim -= 10;
}
g.drawString((i+1) + "", center + (int) anim - 6, center - (int) anim2 + 12);
}
}
}
Lot's of issues -- where to even begin?
You've named a class Component, a name that will easily cause conflicts with a key Java core GUI class, java.awt.Component. Rename it to something else.
This same class extends Applet but is not being used as an Applet. Rather it is being used as a component to be added to a JFrame -- this makes no sense, trying to add one top-level window into another, and would require some justification as to why you're doing it in such a strange fasion. Why not extend JPanel or JComponent something else that makes more sense?
You're using a Graphics field and drawing to it, something that risks NullPointerException. Instead Google and read the Swing drawing tutorials and follow their lead -- draw passively within the paintComponent method of a JPanel. There are other important details to understand which the tutorials will show and tell you.
You're drawing with a Graphics object obtained by calling getGraphics() on a component, something that will lead to unstable drawings and possible NullPointerExceptions. Again read the tutorials on how to do this correctly.
You're making Swing calls in a background thread, something that can lead to intermittent difficult to debug threading errors. Use a Swing Timer to make things easier on yourself. Google the tutorial for the gory details.
You appear to be creating a JPanel, Numbers, but aren't adding it to the GUI (that I can tell), but rather are trying to render it in a strange way -- why, I have no idea. Don't do this. Again do graphics as per the Swing drawing tutorials. Here's the links:
Lesson: Performing Custom Painting: introductory tutorial to Swing graphics
Painting in AWT and Swing: advanced tutorial on Swing graphics
..... more

g.fillPolygon not updating location (Integer arrays not updating...?)

I've come across a problem when trying to move a custom polygon around a JPanel with the mouse; the location for the polygon never updates, even on repaint:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.List;
public class Figure extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public int nPoints = 17, x = 120, y = -60;
int MouseX, MouseY;
final static int SIZE = 400;
public int[] xPoints = {x + 100, x + 85, x + 70, x + 55, x + 40, x + 55, x + 55, x + 40, x + 25, x + 55, x + 55, x + 85, x + 85, x + 115, x + 100, x + 85, x + 85};
public int[] yPoints = {y + 375, y + 385, y + 340, y + 385, y + 375, y + 335, y + 200, y+ 240, y + 225, y + 185, y + 175, y + 175, y + 185, y + 220, y + 240, y + 200, y + 335, y + 375};
List<Integer> xList = new ArrayList<Integer>();
List<Integer> yList = new ArrayList<Integer>();
static final Figure m = new Figure();
public static void main(String[] args){
final JFrame frame = new JFrame();
frame.setTitle("Figure");
frame.getContentPane().add(m);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(SIZE, SIZE);
frame.setResizable(true);
frame.setVisible(true);
m.setBackground(Color.darkGray);
}
public void mouseMovement(){
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
if(((e.getX() >= xPoints[8] && e.getX() <= xPoints[13]) && (e.getY() >= yPoints[10] && e.getY() <= yPoints[1])) || ((e.getX() >= (x + 45) && e.getX() <= (x + 45 + SIZE / 8)) && (e.getY() >= (y + 102) && e.getY() <= (y + 102 + SIZE / (57 / 10))))){
x = e.getX() - 75;
y = e.getY() - 150;
repaint();
}else{
repaint();
}
}
});
}
public Figure(){
mouseMovement();
}
#Override
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.black);
g.fillPolygon(xPoints, yPoints, nPoints);
g.fillPolygon(xPoints, yPoints, nPoints);
g.setColor(Color.white);
g.fillOval(x + 45, y + 102, SIZE / 8, SIZE / (57 / 10));
}
}
My thoughts on this are that the integer array is not updating properly using my predefined variables, but then I come across the problem of not knowing how to properly update it. It seems like it should, considering the location for the oval i made to represent the figure's "head" does, but apparently I'm wrong on that, so I'd like to know why just using the array in fillPolygon doesn't work and how I'd get the location to update. Many thanks in advance.
Use the Polygon class to create a Polygon using your Array of points.
Then in the painting method you can cast the Graphics object to a Graphics2D object and use the Graphics2D.fill(Shape) method to paint the polygon.
When you need to move the Polygon you can use the translate(...) method of the Polygon class.
Also, you should NOT be overriding the paint() method. Custom painting is done by overriding the paintComponent() method.

Transparent circular dialog in Java

I'm building a Poker Odds Calc app in Java. I want to select a new card by clicking the card's placeholder which is basically an extended JPanel that I "draw" the card's face and has a mouseListener.
What I have imagined to do is that when I clicked the card, I would like a round menu to pop up around the mouse cursor having a circle in the middle cut in four with each suite in a quarter and a ring around it cut in thirteen for the value of the card. Then I will select suit and value and it would disappear. Do you know any way I could do this? I researched a bit and I think it can be done with JavaFX by making a transparent JDialog but I'm not sure.
Is there a way to draw a totally custom shaped JComponent like a JButton shaped for each quarter of the circle etc.? I have some experience in Java but not GUI building.
Thanks in advance for your time.
edit: Used your comment and have answered my question about the circular dialog (don't know if it's the best way to do it but works for now). Now, is there anyway I know in which area the click belongs (if the click was on a useful area) without hardcoding the coordinates?
I would suggest doing custom graphics rather than trying to customize JButton and so on. When you click on the JPanel you can draw the circle and so on using the java.awt.Shape interfaces and its various implementations such as java.awt.geom.Ellipse2D.
These shapes come with contains() method that can tell you if a point is in the Shape or not. This way, when the user next clicks on the JPanel, you can determine which shape the user clicked on by going through all the shapes and checking.
The code to create the graphics is this in case anyone needs it:
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D.Double;
import javax.swing.JDialog;
/**
*
* #author Dimitris Klimis <dnklimis at gmail.com>
*/
public class CardChooser extends JDialog implements MouseListener {
int sizeX = 140;
int sizeY = sizeX; //in case I don't want it to be circle
int x, y;
Point point;
public CardChooser(Point point) {
x = point.x;
y = point.y;
this.point = point;
this.initComponents();
}
public static int[] getCard(Point point) {
int[] output = {0, 0};
CardChooser chooser = new CardChooser(point);
return output;
}
#Override
public void paint(Graphics g) {
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//Drawing the transparent dialog
g2.setPaint(new Color(0.0f, 0.0f, 0.0f, 0.0f));
g2.fillRect(0, 0, getWidth(), getHeight());
//Drawing the circles
g2.setColor(Color.BLACK);
drawCircle(g2, 100, new GradientPaint(0.0f, 0.0f, Color.darkGray, (float) getWidth(), (float) getHeight(), Color.lightGray, false));
drawLines(g2, 13, 100);
int smallCircle = 38;
drawCircle(g2, smallCircle + 3, Color.GRAY);
drawCircle(g2, smallCircle, new GradientPaint((float) (getWidth() * 0.25), (float) (getHeight() * 0.25), Color.lightGray, (float) (getWidth() * 0.75), (float) (getHeight() * 0.75), Color.darkGray, false));
drawLines(g2, 4, smallCircle);
drawCircle(g2, 10, Color.LIGHT_GRAY);
drawSuiteLetters(g2);
drawCardValues(g2);
drawClosingX(g2);
} else {
super.paint(g);
}
}
private void drawCircle(Graphics2D g2, int percentage, Paint fill) {
double perc = (double) percentage / 100.0;
Ellipse2D ellipse = new Ellipse2D.Double(((1 - perc) / 2) * sizeX, ((1 - perc) / 2) * sizeY, perc * sizeX, perc * sizeY);
g2.setPaint(fill);
g2.fill(ellipse);
g2.setColor(Color.BLACK);
g2.draw(ellipse);
}
private void drawLines(Graphics2D g2, int outOf, int percentage) {
double rads = Math.toRadians(360.0 / outOf);
double perc = (double) percentage / 100.0;
Double zeroAxis = new Point.Double(sizeX / 2.0, sizeY / 2.0);
for (int i = 0; i < outOf; i++) {
g2.draw(new Line2D.Double(zeroAxis.x, zeroAxis.y, zeroAxis.x + (zeroAxis.x * perc * Math.sin(rads * i)), zeroAxis.y + (zeroAxis.y * perc * Math.cos(rads * i))));
}
}
private void drawSuiteLetters(Graphics2D g2) {
Double zeroAxis = new Point.Double(sizeX / 2.0, sizeY / 2.0);
g2.setFont(new Font("Courier New", Font.BOLD, 25));
g2.drawString("\u2660", (float) zeroAxis.x - 18, (float) zeroAxis.y - 5);//spades
g2.drawString("\u2663", (float) zeroAxis.x + 3, (float) zeroAxis.y + 20);//clubs
g2.setColor(Color.RED);
g2.drawString("\u2665", (float) zeroAxis.x + 3, (float) zeroAxis.y - 3);//hearts
g2.drawString("\u2666", (float) zeroAxis.x - 18, (float) zeroAxis.y + 19);//diamonds
g2.setColor(Color.BLACK);
}
private void drawCardValues(Graphics2D g2) {
Double zeroAxis = new Point.Double((sizeX / 2.0) - 8, 21);
float xx = (float) zeroAxis.x;
float yy = (float) zeroAxis.y;
g2.setFont(new Font("Arial", Font.BOLD, 24));
String[] letters = {"A", "K", "Q", "J", "T", "9", "8", "7", "6", "5", "4", "3", "2"};
float[] xPosition = {0, 25, 46, 63, 58, 42, 15, -10, -37, -53, -58, -46, -25};
float[] yPosition = {0, 7, 23, 50, 80, 102, 115, 115, 102, 80, 50, 23, 7};
for (int i = 0; i < 13; i++) {
g2.drawString(letters[i], xx + xPosition[i], yy + yPosition[i]);
}
}
private void drawClosingX(Graphics2D g2) {
Double zeroAxis = new Point.Double(sizeX / 2.0, sizeY / 2.0);
g2.draw(new Line2D.Double(zeroAxis.x - 5, zeroAxis.y - 5, zeroAxis.x + 5, zeroAxis.y + 5));
g2.draw(new Line2D.Double(zeroAxis.x - 5, zeroAxis.y + 5, zeroAxis.x + 5, zeroAxis.y - 5));
}
private void initComponents() {
this.addMouseListener(this);
this.setBounds(x - (sizeX / 2), y - (sizeY / 2), sizeX + 1, sizeX + 1);
this.setUndecorated(true);
this.setModal(true);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setVisible(true);
}
public void mouseClicked(MouseEvent e) {
this.dispose();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
PS. I extended JDialog cause I couldn't get JPanel to show up...

Categories