I have a project to do and I am completely stuck at this point and have no idea and inspiration on how to continue my code. I have certain tasks and specifications on how to write my code.
This means the code should have a minumum of these classes and methods:
2 enums, one for Color with WHITE and BLACK, and one called ClassPieceType which means KING, QUEEN...
ChessPiece, which is an abstract class and all classes for the types like King, queen which inherit from ChessPiece..
a Board which represents the board with all his figures on it. But I somehow cannot progress on the board and I have no idea on how to implement the methods.
package chess;
public class Board {
public static String[][] chessBoard2() {
String[][] board = new String[8][8];
char letter = 'a';
int number;
for (int row = 0; row < board.length; row++) {
number = 8;
for (int column = 0; column < board[0].length; column++) {
board[row][column] = Character.toString(letter) + number;
number--;
}
letter++;
}
return board;
}
}
This is my idea of a create board method. But the task says
Method has to be public Board() which creates the board in his normal state, and with unicode you have to add the pieces.
But I have no idea on how to implement the unicode, either. And how is it called just public Board? There isn't a return type. I just don't know any more.
I hope someone with HUGE patience can help me. I am just too incompetent to program and we have to hand our task in in several days.
"1. Method has to be public Board() which creates the board in his normal state [...]"
The confusion comes from the fact that such thing is not called a "method" but instead is called a "constructor". It initialize the object you want to create. The goal is that when you write new Board() it does initialize the board with the starting position of chess, something similar to what you are trying with the chessBoard2() method. The Board class can look like this:
public class Board {
private final String[][] board;
public Board() {
this.board = new String[8][8];
Board.fillFirstLine(this.board, 8, Color.BLACK);
Board.fillPawnLine(this.board, 7, Color.BLACK);
Board.fillPawnLine(this.board, 2, Color.WHITE);
Board.fillFirstLine(this.board, 1, Color.WHITE);
}
private static void fillFirstLine(String[][] board, int rowNumber, Color color) {
// ...
}
private static void fillPawnLine(String[][] board, int rowNumber, Color color) {
// ...
}
}
Then somewhere else you write
Board board = new Board();
and you have a fully initialized board ready to use.
"[...] and with unicode you have to add the pieces."
The chess piece icons are present in the unicode charset, see Chess symbols in Unicode. This means you can save the string "\u2654" or the string "♔" inside the array to have this piece at the given position.
Related
Is there any way in Java (Eclipse) to move a player object that is defined as an object on a matrix tile ?
So, the start position of the player object is (0,0). The playboard is a 12x12 matrix. The existing code that I have written works fine to create the player object (as mentioned, as an object on a matrix tile whereby the matrix is defined as [row,col] ).
I am looking to a method to start moving the player based on certain conditions. e.g. a button (I know how to create). So, the question is really how to start moving the player defined as an object on a matrix tile (PlayerPion in the code below).
Thanks in advance for your responses ;).
GamePanel() {
setLimits(BorderFactory.createLineBorder(Color.BLACK, GAP));
GridLayout layout = new GridLayout(GamePanel.getBoardRows(),
GamePanel.getBoardCols());
setLayout(layout);
for (int i = 0; i <PlayBoard.getBoardRows(); i++) {
for (int j = 0; j < PlayBoard.getBoardCols(); j++) {
int[][] matrixBoard = Board.getBoard();
int boardValue = matrixBoard[i][j];
switch(boardValue) {
case AA: add(new Tile(Color.WHITE));
add(new PlayerPion());
break;
(Code that is not relevant is not shown)
A sample of the playBoard (output from existing code):
enter image description here
I am attempting to create a sky-view RPG game, but the initial load times have become a bit of an issue. I am fairly new to programming and Java, so I don't know much about how Java loads things into memory or anything.
So the issue is that when I initially run my program, it can take a very long time for all of my JLabels(set up in my grid) to appear. I am hoping to make a map that is very large, consisting of hundreds of thousands of tiles in total. After doing some math and tests, it turns out that 30 seconds of loading would result in merely about 6,724 tiles. This is only a bit over 8 screens worth of map, which is very small, since my character is a little smaller than 50x50 pixels. So for a map of a size from which I may be satisfied with would take over 6 minutes to load, upon every run. That is insane. And my map creator loads even more slowly.
Each tile is 50x50 pixels. Every tile is set up to have multiple layers of JLabels. For example, the first is for just a JLabel that the other labels will be added to, then the second is for Terrain(like Grass), and the third is for Interactive elements such as doors, so that the door may appear on top of the grass.
All of my Tile objects are created and inserted into a 2-dimensional Tile array. Every Tile instance has:
2 JLabels.
Icons added to at least, and usually only, the first JLabel. Every time a tile requests an icon, it gets it from the MapTiles class.
5 String arrays
7 booleans
4 ints
4 Layer instances in a Layer array of that size
Each Tile instance also implements MouseListener
Each Layer instance has:
1 JLabel with no icon, unless it is Grass. (75% of Layer instances aren't Grass)
4 booleans
1 int
1 String
The MapTiles class will create an ImageIcon for the thing, such as "Grass", if it hasn't already. If it has already created an ImageIcon for it, then it simply returns that ImageIcon. From reading about improving loading times, I was led that this may help speed things up, rather than creating a new ImageIcon for each Tile.
Here, I will provide the beginnings for each of my 3 main classes involved in creating/loading the grid. By beginnings, I mean only the constructor and the creating of the objects. There are a few other methods in each class, but not very many, and none used during the initial loading.
Tile class:
package Tiles;
import Datas.*;
import Images.*;
import MapCreation.*;
import UniversalVariables.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public class Tile implements MouseListener{
public Layer[] layers = new Layer[4];
//MAKE SURE THAT THE FOLLOWING INTEGERS MATCH THE ARRAY IN MAPDATA
int terrain = 0;
int interactive = 1;
int destroyable = 2;
int obstruction = 3;
public JLabel image = new JLabel();
JLabel mouseDetector = new JLabel();
boolean hasBarrier = false;
boolean hasModifiedBarrier = false;
boolean isInteractive = false;
boolean leftClickPressed = false;
boolean rightClickPressed = false;
boolean scrollClickPressed = false;
String[] layerTypes = MapData.uni.tileLayerTypes;
String[] terrainTypes = MapData.uni.terrainTypes;
String[] interactiveTypes = MapData.uni.interactiveTypes;
String[] destroyableTypes = MapData.uni.destroyableTypes;
String[] obstructionTypes = MapData.uni.obstructionTypes;
int tileSize = MapData.uni.tilePixelSize;
int row = 0;
int col = 0;
boolean mapCreatorOpen = UVars.uni.mapCreatorRunning;
public Tile(int rowNum, int colNum){
row = rowNum;
col = colNum;
setLayer("Terrain", "Grass");
for(int c = 1; c < layers.length; c++){ //Sets all layers except terrain to have new layerName
layers[c].layerName = MapData.uni.tileLayerTypes[c] + "NLT";
}
mouseDetector.addMouseListener(this);
image.add(mouseDetector);
mouseDetector.setBounds(0, 0, tileSize, tileSize);
//image.setComponentZOrder(mouseDetector, 0);
for(int c = 0; c < layers.length; c++){
image.setComponentZOrder(layers[c].image, c);
}
image.setComponentZOrder(mouseDetector, 0);
}
}
Layer class:
package Tiles;
import Datas.*;
import Images.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Layer{
public JLabel image = new JLabel();
int tileSize;
public String layerName = "No Layer Name";
boolean hasBarrier;
boolean hasModifiedBarrier;
boolean isInteractive;
boolean affectsMovement;
public Layer(Tile tile, String layerType){
//For empty layers
tile.add(image);
}
public Layer(Tile tile, String layerType, String name){
if(layerType.equals("Terrain") && name.equals("No Layer Name")){
name = "Grass";
}
layerName = name;
tileSize = tile.tileSize;
tile.add(image);
image.setBounds(0, 0, tileSize, tileSize);
image.setIcon(MapTiles.uni.getIcon(layerName));
if(layerType.equals("Terrain")){
Terrain terrain = new Terrain(layerName);
terrain.exchangeValues(this, layerName);
} else if(layerType.equals("Interactive")){
Interactive interactive = new Interactive(layerName);
interactive.exchangeValues(this, layerName);
} else if(layerType.equals("Destroyable")){
Destroyable destroyable = new Destroyable(layerName);
destroyable.exchangeValues(this, layerName);
} else if(layerType.equals("Obstruction")){
Obstruction obstruction = new Obstruction(layerName);
obstruction.exchangeValues(this, layerName);
}
}
}
MapTiles class:
package Images;
import Datas.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public class MapTiles{
public static MapTiles uni;
String tileLoc = "Tile Graphics\\" + String.valueOf(MapData.uni.tilePixelSize) + "PX\\";
ArrayList<ImageIcon> icons = new ArrayList<ImageIcon>();
ArrayList<String> iconList = new ArrayList<String>();
public MapTiles(){
uni = this;
}
public ImageIcon getIcon(String tileType){
for(int c = 0; c < iconList.size(); c++){
if(iconList.get(c).equals(tileType)){
return icons.get(c);
}
}
iconList.add(tileType);
ImageIcon newIcon = new ImageIcon(tileLoc + tileType + ".png");
icons.add(newIcon);
return newIcon;
}
}
So, why does my grid take so long to load? It is all created in the default Java thread, but that's because currently, I don't have any menu or anything else to distract a user with before getting to the map. The map starts immediately. What appears is the frame is just a blank panel. Eventually, once it finally creates the tiles in the top left corner once it has gotten that far(where the user's view defaults), you can see it creating each and the user may even hover on one. (Hovering over it changes the icon set on it) Hovering over it runs very well. Only the load times is the issue. So first off, are there any better ideas you guys have for creating such a grid? Secondly, are there better ways you can think of for doing the things I am attempting to do? And finally, is there anything that I have done wrong that I should improve upon? The main question I guess that I am asking is... What is it that is making Java take so long to load new Tile instance? By the way, I have a fairly high-end PC. It's not some piece of junk. For example, I can run most pre-2015 PC games on maximum graphical settings, and I have 16GB of RAM. I also have another question you guys may be able to answer. I read that using the GPU to load things rather than mainly loading them into RAM runs MUCH more quickly, but it uses 3D Java or something like that. Would I be able to use my GPU to load many of the tiles somehow and improve the load times that way?
Well, it looks like you're loading the same images multiple times from disk for tiles. Only loading what you need, then sharing that same resource in memory could help.
Also you probably shouldn't try to hold your entire map in memory but instead load each section as needed.
I'd recommend you ditch Swing and use LWJGL or an engine backed by LWJGL. This will give you hardware accelerated rendering typically not available through Swing (unless passing certain runtime flags.) If you're concerned about quality Minecraft uses LWJGL. Its really the way to go if you're going to use Java for game development.
Specifically I recommend LIBGDX as your LWJGL backed game framework. I've used it extensively and its a great way to get your game on multiple OS and mobile devices.
having an endless map is not so difficult to achive, it's mainly difficult to maintain
the trick is that you don't load all tiles at once but only load the tiles that are visible, thus called a viewport.
public class ViewPort{
private Tile[][] visibleTiles;
public ViewPort(int width, int height, Factory factory){
//create the Tiles and add them using a proper layout
....
}
public void setViewLocation(int x, int y){
for(int dy = 0; dy < getHeight(); dy++){ //getHeight() with height from constructor
for(int dx = 0; dx < getWidth(); dy++){ //getWidth() with width from constructor
visibleTiles[dx][dy] = factory.getTiles(dx+x, dy+y);
}
}
}
if you use this design you can jump to any location on your map, you only have to use a proper factory.
The harder problem is creating a good factory:
public class Factory{
public Tile getTile(int x, int y){
if (x==0 && y==0) return getTile(TileType.Grass);
...
return null;
}
//speeding up using a lookup table, so we only create objects
//when we need new one / reUse old ones
private Map<TileType, Tile> lookUpTable = ...;
private Tile getTile(TileType type){
Tile value = lookUpTable.get(type);
if(value == null){
value = new Tile(...);
lookUpTable.put(type, value);
}
return value;
}
and what looks kind of easy now is very hard to maintain:
if (x==0 && y==0) return getTile(TileType.Grass);
if (x==1 && y==0) return getTile(TileType.Grass);
this code is neither maintainable nor efficient, you should use switch/case
switch(x){
case 0:
switch (y){
case 0: return getTile(TileType.Grass);
...
}
}
is neither maintainable nor readable...
I am given an assignment to create an Maze with a 2D array.
I am told I need to implement the Union-Find algorithm to generate the mazes of arbitrary size. Then I need to break every wall intill every cell is reachable from every cell.
int[][] matrix = new int[N][M];
The cells are the individual array indexes, but what are the walls? I was thinking of making my own data type of maze with constructors for the 4 directions such as
Maze maze = new Maze() //fill in constructor as needed
The array values are from 0-9, what can I use to represent the walls?
Use ASCII art. You can use '|' for vertical walls and '-' for horizontal walls. It's basic, but once you can ensure that this works, you can move on to graphics that are more pleasing to the eye. It's important to first make sure it's functional before you make it pretty.
I would recommend you to create two Classes, one for your whole Maze and one for a Cell which represents a Coordinate in your Maze. If the Coordinate is actually a wall, use a simple bool value. For your algorithm maybe have a look at https://en.wikipedia.org/wiki/Maze_generation_algorithm
Maybe this snippet gets you started:
public class Maze {
private int X_dim, Y_dim; // the dimension of your maze
private Cell[][] cells; // 2d array of Cells
public Maze(int X_dim, int Y_dim) {
this.X_dim = X_dim;
this.Y_dim = Y_dim;
}
}
public class Cell {
private Point coordinate;
boolean visited = false;
// if true, this Cell represents a wall
boolean wall = true;
Cell(Point coordinate, boolean isWall) {
this.coordinate = coordinate;
this.wall = isWall;
}
}
I would like to move the piece using my mouse.
For example, say there's a pawn sitting on a square on the chess board.
If my mouse was to click (press and release) in the square that the pawn is in, it would be selected. Afterwards, I would click (press and release) in an appropriate square. Say, the square in front of it since that is a proper move in Chess. The pawn would move (get erased from the square it was on, then redrawn on the new one) to the final selected square.
Currently, the Pawn is just sitting on a square when execution is finished.
If it's any help, I am using Ready To Program Java (my teacher told me to) as well as the c console (c = new Console();).
Here is the source code of what I have done so far :)
import hsa.Console;
import java.awt.*;
public class Chess
{
static Console c;
public static void main(String[] args)
{
c = new Console(30, 100); // Rows, Columns (X = 790px && Y = 600px)
Board();
Pawn();
}
public static void Board() // Board: 504px x 504px Square: 63px x 63px
{
int Horizontal = 143; // Board's origin point (X)
int Vertical = 48; // Board's origin point (Y)
for (Vertical = 48; Vertical < 552; Vertical+=63) // Moving onto the next "line"
{
for (Horizontal = 143; Horizontal < 647; Horizontal+=63) // Filling the "line" with squares
{
c.drawRect(Horizontal, Vertical, 63, 63); // Drawing the Squares
}
Horizontal = 143; // Resetting the "line"
}
}
public static void Pawn() // Image and properties of a PAWN piece
{
c.setColor(Color.red); // How the Pawn looks
c.drawOval(143, 111, 63, 63);
}
}
The Console Java class documentation can be found here:
http://stbenedict.wcdsb.ca/hsa/Console.html
As it specifies, it implements the EventListener interface, which has a subinterface, MouseListener. There are many guides online which document how to handle events sent from the MouseListener. Here is one from Oracle's documentation:
https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
I am making a Conway's Game of Life program in java, and am trying to change it from the command line version to a GUI. From the command line I just printed an array which showed the generations (the objects such as blocks and blinkers are shown as a series of 1's and 0's where it is blank, and in the GUI I'm showing it as squares (white squares as blank and blue squares where it isn't). But where I'm getting stuck is when I make another method (which replaces the method which prints the array) which checks the grid array, if there is a zero then the square changes from white to blue, and vice-versa. The Conway's Life rules are dealt with in a separate class which is independent, and all this method does is after the rules have changed the array this method checks it.
The rules are done in methods in one class and the GUI components are done in another. But since I need instance of both how would I go about doing it?, merge the two classes (all the GUI classes into the Life one, embed them some how, I am completely stuck on what to do
public void runGUI() {
int x = getX(), y = getY();
x /= squareSize;
y /= squareSize;
for (int i = 0; i < LifeData.grid.length; i++) {
for (int j = 0; j < LifeData.grid[i].length; j++) {
if (LifeData.grid[i][j] == 0)
l.setCell(x, y, l.getCell(x, y) + 1);
else
l.setCell(x, y, l.getCell(x, y) - 1);
this.repaint();
}
}
}
That is what I have changed it to now but when compiling it is saying "non-static variable grid cannot be referenced from a static context" and "non-static method runGUI() cannot be referenced from a static context". When trying to run the method.
Make a separate thread that will execute the game of life and update the GUI.
Something like this
public class GameExecutor implements Runnable {
private static final int DELAY = 1000;
private GameOfLife game;
private boolean stop = false;
private Gui gui;
public GameExecutor(Gui gui, GameOfLife game) {
this.gui = gui;
this.game = game;
};
public void run(){
game.start();
while (!stop) {
game.step(); //execute a step
gui.update(game.getState());
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {}
}
}
}
Launch this in a thread at startup and pass it your gui. Don't forget to update the gui in the correct Swing thread.
Obviously you'll need to add some code to stop it, too :)