Draw a string on a shape - java

I have an oval and I want to label what it is, for my chess game. I want to use ovals with the names of the pieces on them as strings but I can't seem to get it to work.
Is it even possible to drawString on a shape?
My code
public void drawPieces(Graphics2D g2d){
for(int x = 0; x < 8; x++) {
for(int y = 0; y < 8; y++) {
//reds
if(board[x][y]==24){
g2d.setColor(Color.red);
g2d.fillOval(x*80, y*80, 80, 80);
//drawstring goes here
g2d.setColor(Color.blue);
g2d.drawString("test", x*80, y*80);
}
Any suggestions are welcome
Edit, my grid method in case it helps.
public void drawGrid(Graphics2D g2d){
g2d.drawLine(0, 0, 0, 639);
g2d.drawLine(0, 0, 639, 0);
g2d.drawLine(0, 639, 639, 639);
g2d.drawLine(639, 0, 639, 639);
// draw the horizontal lines using a loop from one to 7, coordiates of each line is (0, x*80, 640, x*80) also
// draw vertical lines with coordinates of (x*80, 0, x*80, 640)
for(int i = 1; i < 8; i++) {
g2d.drawLine(0, i*80, 640, i*80);
g2d.drawLine(i*80, 0, i*80, 640);
}
//drawing the black and white squares
for (int row = 0; row < 8; row++)
for (int col = 0; col < 8; col++) {
if ( (row % 2 == 0 && col % 2 == 0) || ( row % 2 == 1 && col % 2 == 1) ){
g2d.setColor(black);
g2d.fillRect(row*80,col*80,80,80);
}
}
}

I can only say that it is possible to draw a string over an oval, and I'm doing just that in my own game. The top drawing code should be fine. You just need to check the parameter you pass to the drawing method and the if-condition. Here is the excerpt from my code where i draw
over the oval using slightly different method, but your should work too:
public void draw(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.fill(new Ellipse2D.Double(center.x, center.y, itemSize, itemSize));
g2d.setColor(Color.white);
g2d.setFont(new Font("Arial", Font.BOLD, 14));
g2d.drawString(itemName, (int)center.x, (int)center.y+18);
}
itemName is some string, and just not to confuse I thing that first two parametres to
g2d.fill(...(-,-,itemSize, itemSize)) are not the center of elipse but the top left corner of its sourounding rectangle.

Related

How to create multicolor rasterized picture in processing

I followed this tutorial on Youtube, and I have successfully added colors to the black and white picture. However, my intention was to create a multi-color or gradient effect (like here or here) instead of switching colors when I move the cursor.
I very new at processing, and I have tried to play with the variable, with no success.
Here is the code snippet of the sketch:
`
PImage img;
void setup() {
size(598,336);
colorMode(HSB);
img = loadImage("picture-in-data-folder.jpg");
img.resize(598,336);
//ellipseMode(RADIUS);
frameRate(30);
}
void draw() {
background(255);
noStroke();
// fill(0);
float tiles = mouseX/10;
float tileSize = width/tiles;
// color section
fill(color(tiles, 255, 255));
tileSize++;
if (tiles > width / 2) {
tileSize = 0;
}
// end color section
translate(tileSize/2, tileSize/2);
for (int x = 0; x < tiles; x++) {
for (int y = 0; y < tiles; y++) {
color c = img.get(int(x*tileSize),int(y*tileSize));
float size = map(brightness(c), 0, 255, tileSize, 0);
ellipse(x*tileSize, y*tileSize, size, size);
// image(img, mouseX, mouseY);
}
}
}
I would be grateful if you had any hints, or if you could provide an advice.
Thanks.
Short answer: you need to put a fill() command inside the for loop.
Long answer:
Right now, your code is doing the following:
Define tiles based on mouseX
Set the fill color to (tiles, 255, 255)
Draw all the circles
I think what you want it to do is something like this:
Set the fill color to (21, 255, 255) (or whatever you want the first color to be)
draw the first circle
set the fill color to the next color in the gradient
draw the second circle
etc.
In order to do this, you need to put a command into the for loop which changes the fill color. Here is one way to do that:
for (int x = 0; x < tiles; x++) {
for (int y = 0; y < tiles; y++) {
color c = img.get(int(x*tileSize),int(y*tileSize));
float size = map(brightness(c), 0, 255, tileSize, 0);
fill(map(x, 0, tiles, 0, 255), 255, 255);
ellipse(x*tileSize, y*tileSize, size, size);
}
}
I just added that fill command as a function of x, but you can make it whatever you want. In order for it to be a gradient, it needs to vary somewhat with x or y.

How can it save the previous graphics using repaint() in java?

I need to update my graphic, In which there are rectangulars. And at each step I need to highlight and modify the status of some of them.
But now in my code, for each repaint(), it draw a totally new picture.
I have read the followint similar quesion:
Keeping draw graphics - removing super.paintComponent ,which cannot solve my problem.
The next time it calls repaint(), those rectangulars disappear. It means it erases the prevous graphic.
Please help!
Here is the code: ("firstPaint = false" is just before the next repaint())
#Override
protected void paintComponent(Graphics g2)
{
super.paintComponent(g2);
final Graphics2D g = (Graphics2D) g2.create();
try{
if(firstPaint){
int status;
g.setColor(Color.BLACK);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
status = current[i][j];
if(status == 1)
{
g.fillRect(j * 20, i * 20, 20, 20);
}
}
}
}
if(executeResult == 2){
g.setColor(Color.BLUE);
for(Cell c:highlightedCells){
g.drawRect(c.j * 20, c.i * 20, 20, 20);
}
}
if(executeResult == 1){
g.setColor(Color.RED);
for(Cell c:highlightedCells){
g.fillRect(c.j * 20, c.i * 20, 5, 5);
}
}
}
finally{
g.dispose();
}
}

Code Flutter (lines kind of jump and look bad)

So I have this little program (or sketch if you like). My problem is, and how should I word this, that the lines, when they are moving, kind of jitter and flutter a bit. Is this to do with the processing power of my computer, or should I code this in a different manner?
This is the code:
int i, j;
void setup() {
size(1440, 900);
background(0);
smooth();
strokeWeight(10);
i = width/2 - (width/2);
j = width;
}
void draw() {
fill(0, 10); // semi-transparent black
stroke(0);
rect(0, 0, width, height); //legger seg lag på lag
if (i < width-200) {
i+=4;
j-=4;
}
else {
i = width/2 - (width/2);
j = width;
}
stroke(255);
line(width/2, height, i, 30);
line(width/2, height, i+40, 30);
line(width/2, height, i+80, 30);
line(width/2, height, i+120, 30);
line(width/2, height, i+160, 30);
line(width/2, height, i+200, 30);
line(width/2, height, j, 30);
line(width/2, height, j-40, 30);
line(width/2, height, j-80, 30);
line(width/2, height, j-120, 30);
line(width/2, height, j-160, 30);
line(width/2, height, j-200, 30);
}
After doing a quick profile with JVisualVM it turns out that there are two culprits:
Rendering lines
Handling anti-aliased transparency
Rending lines:
Behind the scenes Processing is rendering each line as a shape(beginShape()/endShape()), in this case using LINES. You can give Processing a hand, and rather than using multiple beginShape/endShape calls(1 per line), just use one for all your lines:
beginShape(LINES);
for(int k = 0; k < 200; k+= 40){
vertex(hw, height);vertex(i+k, 30);
vertex(hw, height);vertex(j-k, 30);
}
endShape();
Anti-alias and transparency
Using transparency is generally computationally expensive, especially for large images.
Running the snippet bellow, press the mouse button and see how frameRate changes when transparency isn't used.
Anti-aliasing is also computationally expensive. Not as much as transparency, but in addition too, it makes a difference. Press any key to toggle between aliased and anti-aliased graphics
Here are a few tweaks to your code:
int i, j;
int hw;
boolean smooth;
void setup() {
size(1440, 900);
background(0);
strokeWeight(10);
hw = width/2;
i = width/2 - (width/2);//isn't this 0 ?
j = width;
}
void draw() {
fill(0,mousePressed ? 255 : 10); // semi-transparent black
noStroke();
rect(0, 0, width, height); //legger seg lag på lag
if (i < width-200) {
i+=4;
j-=4;
}
else {
i = 0;
j = width;
}
stroke(255);
beginShape(LINES);
for(int k = 0; k < 200; k+= 40){
vertex(hw, height);vertex(i+k, 30);
vertex(hw, height);vertex(j-k, 30);
}
endShape();
frame.setTitle((int)frameRate+" fps, smooth: " + smooth);
}
void keyReleased(){
smooth = !smooth;
if(smooth) smooth();
else noSmooth();
}

Algorithm that searches a 2D array

I'm trying to recreate a tetris-like game. I have a 2D array, "_tiles" that stores objects called "ColorShape" .
private ColorShape[][] _tiles = new ColorShape[8][17];;
im trying to make a quickDrop() method for when I hit the down arrow key to find the next available slot in the array to quickly place the shapes. I am having a hard time figuring out the algorithm that will search the rows below the current piece in the column that the piece is in.
This is what I tried to do so far but I think that I am going about this all wrong: (the Pieces are 30x30 pixels thats why they are being divided by 30, so that the array location corresponds to the x and y locations of the shape)
public void quickDrop(){
// j is the column that the piece is currently in
int j = _proxyPiece.getXLocation()/30;
for (int i=0; i<17;i++){
if(_tiles[j][i] == null)
continue;
else if (_tiles[j][i] != null){
_tiles[j][i-2] = _proxyPiece.getFirstPiece();
_tiles[j][i-1] = _proxyPiece.getSecondPiece();
repaint();
_proxyPiece.setPiece(this.newPiece());
repaint();
break;
}
}
}
public void paintComponent(Graphics g) {
if (_pauseState == false){
_pauseText.setVisible(false);
super.paintComponent(g);
// simplify the positioning of things.
g.translate(0, 0);
//Draws the board outline and fills it white
g.setColor(Color.WHITE);
g.drawRect(0, 0, 240, 480);
g.fillRect(0, 0, 240, 480);
//Draws a dark gray grid
g.setColor(Color.DARK_GRAY);
for(int x = 0; x < COL_COUNT + 1; x++) {
for(int y = 0; y < VISIBLE_ROW_COUNT+1; y++) {
g.drawLine(0, y * TILE_SIZE, COL_COUNT * TILE_SIZE, y * TILE_SIZE);
g.drawLine(x * TILE_SIZE, 0, x * TILE_SIZE, VISIBLE_ROW_COUNT * TILE_SIZE);
}
}
Graphics2D aBetterPen = (Graphics2D)g;
_proxyPiece.fill(aBetterPen);
for (int i = 0; i<16; i++){
for(int j=0; j<8;j++){
if(_tiles[j][i] != null)
_tiles[j][i].fill(aBetterPen);
}
}
}
else if (_pauseState == true){
_pauseText.setVisible(true);
super.paintComponent(g);
// simplify the positioning of things.
g.translate(0, 0);
g.setColor(Color.WHITE);
g.drawRect(0, 0, 240, 480);
g.fillRect(0, 0, 240, 480);
}
}
One algorithm to solve this:
Take the current dropping piece and move it over every Y value from its current position downwards.
If it collides with a previously placed piece, or exceeds the bottom of your grid, the last Y position you checked is a valid solution.
If you want all valid solutions instead of just one, repeat this algorithm for all possible rotations of the currently selected piece.
Here's an example of the algorithm. It won't work with your code as is, but it will get you off to a quick start.
ColorShape[][] grid = new ColorShape[width][height];
TetrisShape shape = new TetrisShape(Shape.L_SHAPE);
//position will be bottom left coordinate of bounding rectangle of dropping shape.
Point position = new Point(shape.getPosition());
int resultY = -1;
for(int dy=0;dy<height;dy++){
for(int y=0;y<height;y++){
int shapeY = position.y+y;
if(shapeY>=height || shape.intersectsGrid(grid)){
resultY = shapeY -1;
break;
}
}
}

How to draw a transparent line?

I am drawing a solid blue line on a JPanel via
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
super.paint(g2);
if (path.size() >= 2) {
BasisStroke stroke = new BasicStroke(Config.TILE_SIZE_IN_PIXEL / 3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
g2.setStroke(stroke);
g2.setPaint(Color.BLUE);
g2.setPaintMode();
for (int i = 0; i < path.size() - 1; i++) {
g2.drawLine(path.get(i).x, path.get(i).y, path.get(i + 1).x, path.get(i + 1).y);
}
}
}
Yet I want this line to be semi-transparent. How do I achieve that?
The short answer is to set the alpha for the color of your graphic context:
float alpha = 0.5;
Color color = new Color(1, 0, 0, alpha); //Red
g2.setPaint(color);
Alpha ranges between 0.0f (invisible) to 1.0f (opaque)
For the long answer with examples, see this article.

Categories