This is a maze solver and I am trying to find a path through the maze. The Map is generated using Prim's algorithm and the position class which is added at the end.
I am trying to find an optimal path through the randomly generated maze using BFS, A*, or DFS but I seem to be doing something wrong.
//impoted by wildcard
import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
public class MazeGenerator extends Canvas {
private final Random rand = new Random(); //random variable
private static int WIDTH;
private static int HEIGHT;
private int TILE_WIDTH = 15;
private int TILE_HEIGHT = 15;
private static LinkedList <position> maze = new LinkedList<>(); // maze
private static Map<position, Color> colors = new HashMap<>();
// paint class to draw out the maze
public void paint(Graphics g) {
super.paint(g);
g.translate(5, 5);
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, WIDTH * TILE_WIDTH, HEIGHT * TILE_HEIGHT);
g.setColor(Color.LIGHT_GRAY);
g.drawLine(0, 0, 0, HEIGHT * TILE_HEIGHT);
g.drawLine(0, 0, WIDTH * TILE_WIDTH, 0);
g.drawLine(WIDTH * TILE_WIDTH, 0, WIDTH * TILE_WIDTH, HEIGHT * TILE_HEIGHT);
g.drawLine(0, HEIGHT * TILE_HEIGHT, WIDTH * TILE_WIDTH, HEIGHT * TILE_HEIGHT);
LinkedList <position> mazeSteped = maze;
for(int y = 0; y < HEIGHT; y++)
{
for(int x = 0; x < WIDTH; x++)
{
int current = (y * WIDTH) + x;
int lower = ((y + 1) * WIDTH) + x;
if(!mazeSteped.contains(new position(current, lower)))
g.drawLine(x * TILE_WIDTH, (y + 1) * TILE_HEIGHT, (x + 1) * TILE_WIDTH, (y + 1) * TILE_HEIGHT);
if(!mazeSteped.contains(new position(current, current + 1)))
g.drawLine((x + 1) * TILE_WIDTH, y * TILE_HEIGHT, (x + 1) * TILE_WIDTH, (y + 1) * TILE_HEIGHT);
if(colors.containsKey(new position(x, y)))
{
g.setColor(colors.get(new position(x, y)));
g.fillRect(x * TILE_WIDTH, y * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
g.setColor(Color.LIGHT_GRAY);
}
}
}
}
// Prim's algorithm
public void generate(int Width, int Height)
{
LinkedList<Integer> visited = new LinkedList<>();
LinkedList<position> toVisit = new LinkedList<>();
visited.add(0);
toVisit.add(new position(0, 1));
toVisit.add(new position(0, Width));
while(toVisit.size() > 0)
{
int randomIndex = rand.nextInt(toVisit.size());
position nextPath = toVisit.remove(randomIndex);
if(visited.contains(nextPath.end))
continue;
if(nextPath.start > nextPath.end)
maze.add(new position(nextPath.end, nextPath.start));
else
maze.add(nextPath);
visited.add(nextPath.end);
//this is showing all four directions that the random variable can generate towards.
int above = nextPath.end - Width;
if(above > 0 && !visited.contains(above))
toVisit.add(new position(nextPath.end, above));
int left = nextPath.end - 1;
if(left % Width != Width - 1 && !visited.contains(left))
toVisit.add(new position(nextPath.end, left));
int right = nextPath.end + 1;
if(right % Width != 0 && !visited.contains(right))
toVisit.add(new position(nextPath.end, right));
int below = nextPath.end + Width;
if(below < Width * Height && !visited.contains(below))
toVisit.add(new position(nextPath.end, below));
}
}
public static void main(String[] args)
{
MazeGenerator mazeGen = new MazeGenerator();
int Height = 30;
HEIGHT = Height;
int Width = 30;
WIDTH = Width;
mazeGen.generate(Width, Height);
mazeGen.setSize(16*Width, 17*Height);
JFrame frame = new JFrame("Maze Generator");
frame.add(mazeGen);
frame.setSize(16*Width, 17*Height);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//position or vector class that keeps track of position.
public class position{
public int start;
public int end;
public position(int start, int end){
this.start = start;
this.end = end;
}
public String toString(){
return "(" + start + ", " + end + ")";
}
public boolean equals(Object obj){
if(!(obj instanceof position))
return false;
position pos = (position) obj;
return pos.start == start && pos.end == end;
}
public int hashCode(){
return this.toString().hashCode();
}
public static void main(String [] args) {
position my = new position(1,1);
System.out.println(new position(1,1));
}
}
https://github.com/yuchinchenTW/MazeGenerate/tree/master
try this maze generator
using depth-first search and Recursive division method
The recursive division method can prevent stackoverflow on recursion
https://en.wikipedia.org/wiki/Maze_generation_algorithm
Related
I'm trying to print out a maze. I'm new to Java Swing graphics, and my initial thought was to add JPanel components of each cell to the JFrame. I get garbage results when I run this code.
Is there any way I can change this code minimally so that all the panels are printed? Note that CurrPos, Wall, Unvisited, and Visited are subclasses of JFrame, which implement the painComponent method.
Here's the code:
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DrawMaze {
public final int WIDTH = 500;
public final int HEIGHT = 500;
JFrame frame;
public void initializeMaze(){
frame = new JFrame("Maze");
frame.getContentPane().setLayout(null);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void drawMaze(String[][] maze, int[] currPosArray) {
//frame.removeAll();
addMazeContentsToList(maze, currPosArray);
frame.setVisible(true);
}
private void addMazeContentsToList(String[][] maze, int[] currPosArray) {
for (int i = 0; i<7; i++){
for (int j = 0; j<9; j++){
if ((i%2 == 1 && j%2 == 0) ||(i%2 == 0 && j%2 == 1) ){
Wall wall = drawWall(i, j);
frame.add(wall);
wall.repaint();
}
else if (i%2 ==0 && j%2 ==0){
if (i==currPosArray[0] && j==currPosArray[1]){
CurrPos currPos = drawCurrPos(i/2, j/2);
frame.add(currPos);
currPos.repaint();
}
else{
if (maze[i][j].equals("Unexplored")){
Unvisited unvisited = drawUnvisited(i/2,j/2);
frame.add(unvisited);
unvisited.repaint();
}
else{
Visited visited = drawVisited(i/2,j/2);
frame.add(visited);
visited.repaint();
}
}
}
}
}
}
private Visited drawVisited(int i, int j) {
int x = (int) Math.floor((i/4.0)*WIDTH);
int y = (int) Math.floor((j/5.0)*HEIGHT);
int width = (int) Math.floor(WIDTH/4.0);
int height = (int) Math.floor(HEIGHT/5.0);
return new Visited(x, y, width, height);
}
private Unvisited drawUnvisited(int i, int j) {
int x = (int) Math.floor((i/4.0)*WIDTH);
int y = (int) Math.floor((j/5.0)*HEIGHT);
int width = (int) Math.floor(WIDTH/4.0);
int height = (int) Math.floor(HEIGHT/5.0);
//System.out.println(x);
//System.out.println(y);
System.out.println(width);
System.out.println(height);
return new Unvisited(x, y, width, height);
}
private CurrPos drawCurrPos(int i, int j) {
int x = (int) Math.floor((i/4.0)*WIDTH);
int y = (int) Math.floor((j/5.0)*HEIGHT);
int width = (int) Math.floor(WIDTH/4.0);
int height = (int) Math.floor(HEIGHT/5.0);
return new CurrPos(x, y, width, height);
}
private Wall drawWall(int i, int j) {
//vertical wall
if (i%2 ==1){
int relativeX = (i+1)/2;
int relativeY = j/2;
int width = (int) Math.floor((1/4.0)*WIDTH*(0.2));
int height = (int) Math.floor((1/5.0)*HEIGHT);
int x = (int) Math.floor(((relativeX/4.0)*WIDTH - width*0.5));
int y = (int) (Math.floor((relativeY/5.0)*HEIGHT));
return new Wall(x, y, width, height);
}
//horizontal wall
else{
int relativeX = i/2;
int relativeY = (j+2)/2;
int width = (int) Math.floor((1/4.0)*WIDTH);
int height = (int) Math.floor((1/5.0)*HEIGHT*(0.2));
int x = (int) (Math.floor((relativeY/4.0)*WIDTH));
int y = (int) Math.floor(((relativeX/5.0)*HEIGHT - height*0.5));
return new Wall(x, y, width, height);
}
}
}
I am well and truly stuck on this method. I need to create an attack method for a ComputerPlayer that chooses a random location and attacks the other player's board. Then, there is an attack method where I have to just attack the other player's board. However, when I run the program and place my guesses on my board (GUI), the dots just appear on the ComputerPlayer's board. I don't know why my methods are wrong though.
/**
* Attack the specified Location loc. Marks
* the attacked Location on the guess board
* with a positive number if the enemy Player
* controls a ship at the Location attacked;
* otherwise, if the enemy Player does not
* control a ship at the attacked Location,
* guess board is marked with a negative number.
*
* If the enemy Player controls a ship at the attacked
* Location, the ship must add the Location to its
* hits taken. Then, if the ship has been sunk, it
* is removed from the enemy Player's list of ships.
*
* Return true if the attack resulted in a ship sinking;
* false otherwise.
*
* #param enemy
* #param loc
* #return
*/
#Override
public boolean attack(Player enemy, Location loc)
{
int[][] array = getGuessBoard();
if(!enemy.hasShipAtLocation(loc))
array[loc.getRow()][loc.getCol()] = -1;
else
{
array[loc.getRow()][loc.getCol()] = 1;
enemy.getShip(loc).takeHit(loc);
}
if(enemy.getShip(loc).isSunk()) {
enemy.removeShip(enemy.getShip(loc));
return true;
}
return false;
}
#Override
public boolean attack(Player enemy, Location loc)
{
int range = (10 - 0) + 1;
int r = (int) Math.random() * range;
int c = (int) Math.random() * range;
int[][] array = getGuessBoard();
if(array[r][c] != -1)
{
if(!enemy.hasShipAtLocation(loc))
array[loc.getRow()][loc.getCol()] = -1;
else
{
array[loc.getRow()][loc.getRow()] = 1;
enemy.getShip(loc).takeHit(loc);
}
if(getShip(loc).isSunk())
{
enemy.removeShip(enemy.getShip(loc));
return true;
}
}
return false;
}
GUI for Game
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class BattleshipDriver extends Canvas implements MouseListener
{
public static final int WIDTH = 1024, HEIGHT = WIDTH / 12 * 9;
private Battleship battleship;
private int x, y, squareSize, len;
private Player p1, p2;
private BufferedImage logo, end;
public BattleshipDriver()
{
battleship = new Battleship();
battleship.addPlayer(new HumanPlayer("Mr. Hubbard"));
battleship.addPlayer(new ComputerPlayer("AlphaBattleship"));
x = 90;
y = 200;
squareSize = 36;
len = squareSize * 10 - 1;
p1 = battleship.getPlayer(0);
p2 = battleship.getPlayer(1);
// Get Battleship Logo
try {
logo = ImageIO.read(new File("src/Logo.png"));
} catch (IOException e) {
e.printStackTrace();
}
// Get End Screen
try {
end = ImageIO.read(new File("src/End.png"));
} catch (IOException e) {
e.printStackTrace();
}
addMouseListener(this);
new Window(WIDTH, HEIGHT, "Battleship", this);
try {
Thread.sleep(100);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
render();
}
private void render()
{
Graphics g = getGraphics();
// Background
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, WIDTH, HEIGHT);
if(!battleship.gameOver())
{
// Boards
renderGrid(g, x, y, squareSize);
renderGuesses(g, p1, x, y, squareSize);
renderGrid(g, 570, y, squareSize);
renderGuesses(g, p2, 570, y, squareSize);
// Names
g.setColor(Color.WHITE);
g.drawString(p1.getName(), x, y + 25 + len);
g.drawString(p2.getName(), 570, y + 25 + len);
}
else
{
// End Screen
g.drawImage(end, 0, 0, this);
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", 1, squareSize));
String winner = battleship.getWinner().getName();
g.drawString(winner, WIDTH / 2 - (winner.length() * squareSize / 4), HEIGHT / 4);
g.drawString("Wins!", WIDTH / 2 - ("Wins!".length() * squareSize / 4), HEIGHT / 4 + squareSize);
}
// Battleship Logo
g.drawImage(logo, WIDTH / 2 - 246, 10, this);
g.dispose();
}
private void renderGrid(Graphics g, int x, int y, int s)
{
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", 1, s / 2));
// Row Lines
for(int i = 0; i < 11; i++)
g.drawLine(x, y+i*s, x+len, y+i*s);
// Column Lines
for(int i = 0; i < 11; i++)
g.drawLine(x+i*s, y, x+i*s, y+len);
// Row Markers
for(int i = 0; i < 10; i++) //marks row coordinates on side
g.drawString(i + "", x-(int)(s*0.43), y+(int)(s*0.67)+s*i);
// Column Markers
for(int i = 0; i < 10; i++) //marks column coordinates on top
g.drawString(i + "", x+(int)(s*0.4)+s*i, y-(int)(s*0.2));
}
public void renderGuesses(Graphics g, Player player, int x, int y, int s)
{
int[][] guessBoard = player.getGuessBoard();
for(int r = 0; r < guessBoard.length; r++)
for(int c = 0; c < guessBoard[r].length; c++)
if(guessBoard[r][c] > 0) // hit
{
g.setColor(Color.RED);
g.fillOval(c*s+x+(int)(s*0.35), r*s+y+(int)(s*0.35), (int)(s*0.33), (int)(s*0.33));
}
else if(guessBoard[r][c] < 0) // miss
{
g.setColor(Color.WHITE);
g.fillOval(c*s+x+(int)(s*0.35), r*s+y+(int)(s*0.35), (int)(s*0.33), (int)(s*0.33));
}
}
#Override
public void mouseClicked(MouseEvent e)
{
int r = e.getY();
int c = e.getX();
int len = squareSize * 10 - 1;
if(r > y && r < y + len && c > x && c < x + len) // clicked on board
{
int row = (r - y) / squareSize;
int col = (c - x) / squareSize;
System.out.println(row + ", " + col);
Location loc = new Location(row, col);
if(p1.getGuessBoard()[row][col] == 0)
{
p1.attack(p2, loc);
p2.attack(p1, loc);
}
battleship.upkeep();
render();
}
System.out.println(r + ", " + c);
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
public static void main(String[] args)
{
new BattleshipDriver();
}
}
I have a problem with a hexagonal grid. I found this code you can see below on Internet, so it's not mine. There are two public classes: hexgame which generates the grid and hexmech which draws and fills every single hexagon. What I'd like to do is basically insert an image into a specific hexagon, but I don't know how to code this and in which part of the classes I should put it. Am I thinking the wrong way?
Thank you very much for your help!
Hexgame
package hex;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class hexgame
{
private hexgame() {
initGame();
createAndShowGUI();
}
final static Color COLOURBACK = Color.WHITE;
final static Color COLOURCELL = Color.WHITE;
final static Color COLOURGRID = Color.BLACK;
final static Color COLOURONE = new Color(255,255,255,200);
final static Color COLOURONETXT = Color.BLUE;
final static Color COLOURTWO = new Color(0,0,0,200);
final static Color COLOURTWOTXT = new Color(255,100,255);
final static Color COLOURSAFE = Color.WHITE;
final static Color COLOURDANGEROUS = Color.LIGHT_GRAY;
final static int EMPTY = 0;
final static int UNKNOWN = -1;
final static int SAFE = 1;
final static int DANGEROUS = 2;
final static int CLICKED = 3;
final static int COLUMN_SIZE = 23;
final static int ROW_SIZE = 14;
final static int HEXSIZE = 45;
final static int BORDERS = 15;
int[][] board = new int[COLUMN_SIZE][ROW_SIZE];
void initGame(){
hexmech.setXYasVertex(false);
hexmech.setHeight(HEXSIZE);
hexmech.setBorders(BORDERS);
for (int i=0;i<COLUMN_SIZE;i++) {
for (int j=0;j<ROW_SIZE;j++) {
board[i][j]=EMPTY;
}
}
board[5][5] = SAFE;
board[5][6] = SAFE;
board[5][7] = SAFE;
board[6][5] = SAFE;
board [6][6] = SAFE;
board[4][4] = UNKNOWN;
}
private void createAndShowGUI()
{
DrawingPanel panel = new DrawingPanel();
JFrame frame = new JFrame("Hex Testing 4");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
Container content = frame.getContentPane();
content.add(panel);
frame.setSize(825, 630);
frame.setResizable(true);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
class DrawingPanel extends JPanel
{
public DrawingPanel()
{
setBackground(COLOURBACK);
MyMouseListener ml = new MyMouseListener();
addMouseListener(ml);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setFont(new Font("TimesRoman", Font.PLAIN, 15));
super.paintComponent(g2);
for (int i=0;i<COLUMN_SIZE;i++) {
for (int j=0;j<ROW_SIZE;j++) {
if (board[i][j] != UNKNOWN)
hexmech.drawHex(i,j,g2);
}
}
for (int i=0;i<COLUMN_SIZE;i++) {
for (int j=0;j<ROW_SIZE;j++) {
if (board[i][j] != UNKNOWN)
hexmech.fillHex(i,j,board[i][j],g2);
}
}
}
class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
Point p = new Point( hexmech.pxtoHex(e.getX(),e.getY()) );
if (p.x < 0 || p.y < 0 || p.x >= COLUMN_SIZE || p.y >= ROW_SIZE) return;
board[p.x][p.y] = CLICKED;
repaint();
}
}
}
}
Hexmech
package hex;
import java.awt.*;
import javax.swing.*;
public class hexmech
{
#define HEXEAST 0
#define HEXSOUTHEAST 1
#define HEXSOUTHWEST 2
#define HEXWEST 3
#define HEXNORTHWEST 4
#define HEXNORTHEAST 5
public final static boolean orFLAT= true;
public final static boolean orPOINT= false;
public static boolean ORIENT= orFLAT;
public static boolean XYVertex=true;
private static int BORDERS=50
private static int s=0; // length of one side
private static int t=0; // short side of 30o triangle outside of each hex
private static int r=0; // radius of inscribed circle (centre to middle of each side). r= h/2
private static int h=0; // height. Distance between centres of two adjacent hexes. Distance between two opposite sides in a hex.
public static void setXYasVertex(boolean b) {
XYVertex=b;
}
public static void setBorders(int b){
BORDERS=b;
}
public static void setSide(int side) {
s=side;
t = (int) (s / 2); //t = s sin(30) = (int) CalculateH(s);
r = (int) (s * 0.8660254037844);
h=2*r;
}
public static void setHeight(int height) {
h = height;
r = h/2; // r = radius of inscribed circle
s = (int) (h / 1.73205); // s = (h/2)/cos(30)= (h/2) / (sqrt(3)/2) = h / sqrt(3)
t = (int) (r / 1.73205); // t = (h/2) tan30 = (h/2) 1/sqrt(3) = h / (2 sqrt(3)) = r / sqrt(3)
}
public static Polygon hex (int x0, int y0) {
int y = y0 + BORDERS;
int x = x0 + BORDERS;
if (s == 0 || h == 0) {
System.out.println("ERROR: size of hex has not been set");
return new Polygon();
}
int[] cx,cy;
if (XYVertex)
cx = new int[] {x,x+s,x+s+t,x+s,x,x-t}; //this is for the top left vertex being at x,y. Which means that some of the hex is cutoff.
else
cx = new int[] {x+t,x+s+t,x+s+t+t,x+s+t,x+t,x}; //this is for the whole hexagon to be below and to the right of this point
cy = new int[] {y,y,y+r,y+r+r,y+r+r,y+r};
return new Polygon(cx,cy,6);
}
public static void drawHex(int i, int j, Graphics2D g2) {
int x = i * (s+t);
int y = j * h + (i%2) * h/2;
Polygon poly = hex(x,y);
g2.setColor(hexgame.COLOURCELL);
//g2.fillPolygon(hexmech.hex(x,y));
g2.fillPolygon(poly);
g2.setColor(hexgame.COLOURGRID);
g2.drawString(String.format("%c;%d", 'A'+i, j+1), x+20, y+40);
g2.drawPolygon(poly);
}
public static void fillHex(int i, int j, int n, Graphics2D g2) {
char c='o';
int x = i * (s+t);
int y = j * h + (i%2) * h/2;
/*if (n < 0) {
g2.setColor(hexgame.COLOURONE);
g2.fillPolygon(hex(x,y));
g2.setColor(hexgame.COLOURONETXT);
c = (char)(-n);
g2.drawString(""+c, x+r+BORDERS, y+r+BORDERS+4); //FIXME: handle XYVertex
//g2.drawString(x+","+y, x+r+BORDERS, y+r+BORDERS+4);
}
if (n > 0) {
g2.setColor(hexgame.COLOURTWO);
g2.fillPolygon(hex(x,y));
g2.setColor(hexgame.COLOURTWOTXT);
c = (char)n;
if (n==3) {
g2.setColor(hexgame.COLOURTWO);
g2.fillPolygon(hex(x,y));
g2.setColor(hexgame.COLOURTWOTXT);
}
}
public static Point pxtoHex(int mx, int my) {
Point p = new Point(-1,-1);
//correction for BORDERS and XYVertex
mx -= BORDERS;
my -= BORDERS;
if (XYVertex) mx += t;
int x = (int) (mx / (s+t));
int y = (int) ((my - (x%2)*r)/h);
int dx = mx - x*(s+t);
int dy = my - y*h;
if (my - (x%2)*r < 0) return p; // prevent clicking in the open halfhexes at the top of the screen
//System.out.println("dx=" + dx + " dy=" + dy + " > " + dx*r/t + " <");
//even columns
if (x%2==0) {
if (dy > r) { //bottom half of hexes
if (dx * r /t < dy - r) {
x--;
}
}
if (dy < r) { //top half of hexes
if ((t - dx)*r/t > dy ) {
x--;
y--;
}
}
} else { // odd columns
if (dy > h) { //bottom half of hexes
if (dx * r/t < dy - h) {
x--;
y++;
}
}
if (dy < h) { //top half of hexes
//System.out.println("" + (t- dx)*r/t + " " + (dy - r));
if ((t - dx)*r/t > dy - r) {
x--;
}
}
}
p.x=x;
p.y=y;
return p;
}
In your implementation of paintComponent(), invoke setClip() with a suitable Shape, such as Polygon. You can size and translate the Polygon to match the destination hexagon using the createTransformedShape() method of AffineTransform. Use the coordinates of the polygon's boundary as the basis for the coordinates used in your call to drawImage(). A related example using Ellipse2D is shown here.
I'm pretty fresh to java but I wanted to create a exploration type game. I researched for the last 2 weeks and was able to implement the diamond square algorithm for some pretty sweet terrain. But now I'm having trouble trying figure out how to move the map and how to continue the random generation. Here's what I have so far.
Game.java
package com.game.main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.Random;
//import java.util.Random;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 5420209024354289119L;
public static final int WIDTH = 1000, HEIGHT = WIDTH / 12 * 9;
private Thread thread;
private boolean running = false;
//private Random r;
private Handler handler;
public Game(){
handler = new Handler();
this.addKeyListener(new KeyInput(handler));
new Window(WIDTH, HEIGHT, "Game", this);
final int[][] map = DSAlgorithm.makeHeightMap(10, 45, 200);
//r = new Random();
handler.addObject(new Player(WIDTH/2 - 32, HEIGHT/2 - 32, ID.Player));
//handler.addObject(new World(0, 0, ID.World));
int squareSize = 10;
for(int y = 0; y < map.length; y+=squareSize){
for(int x = 0; x < map.length; x+=squareSize){
int value = map[x][y];
handler.addObject(new TerrianTile(x, y, value));
}
}
}
public synchronized void start(){
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop(){
try {
thread.join();
running = false;
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(){
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while (running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1){
tick();
delta --;
}
if (running)
render();
frames++;
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
private void tick(){
handler.tick();
}
private void render(){
BufferStrategy bs = this.getBufferStrategy();
if (bs == null){
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
handler.render(g);
g.dispose();
bs.show();
}
public static void main(String args[]){
new Game();
}
public static int randInt(int min, int max){
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
}
Window.java
package com.game.main;
import java.awt.Canvas;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Window extends Canvas {
private static final long serialVersionUID = -1478604005915452565L;
public Window(int width, int height, String title, Game game) {
JFrame frame = new JFrame(title);
frame.setPreferredSize(new Dimension(width, height));
frame.setMaximumSize(new Dimension(width, height));
frame.setMinimumSize(new Dimension(width, height));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.add(game);
frame.setVisible(true);
game.start();
}
}
DSAlgorithm.java
package com.game.main;
public class DSAlgorithm {
/**
* This method uses the seed value to initialize the four corners of the
* map. The variation creates randomness in the map. The size of the array
* is determined by the amount of iterations (i.e. 1 iteration -> 3x3 array,
* 2 iterations -> 5x5 array, etc.).
*
* #param iterations
* the amount of iterations to do (minimum of 1)
* #param seed
* the starting value
* #param variation
* the amount of randomness in the height map (minimum of 0)
* #return a height map in the form of a 2-dimensional array containing
* integer values or null if the arguments are out of range
*/
public static int[][] makeHeightMap(int iterations, int seed, int variation) {
if (iterations < 1 || variation < 0) {
return null;
}
int size = (1 << iterations) + 1;
int[][] map = new int[size][size];
final int maxIndex = map.length - 1;
// seed the corners
map[0][0] = seed;
map[0][maxIndex] = seed;
map[maxIndex][0] = seed;
map[maxIndex][maxIndex] = seed;
for (int i = 1; i <= iterations; i++) {
int minCoordinate = maxIndex >> i;// Minimum coordinate of the
// current map spaces
size = minCoordinate << 1;// Area surrounding the current place in
// the map
diamondStep(minCoordinate, size, map, variation);
squareStepEven(minCoordinate, map, size, maxIndex, variation);
squareStepOdd(map, size, minCoordinate, maxIndex, variation);
variation = variation >> 1;// Divide variation by 2
}
return map;
}
/**
* Calculates average values of four corner values taken from the smallest
* possible square.
*
* #param minCoordinate
* the x and y coordinate of the first square center
* #param size
* width and height of the squares
* #param map
* the height map to fill
* #param variation
* the randomness in the height map
*/
private static void diamondStep(int minCoordinate, int size, int[][] map,
int variation) {
for (int x = minCoordinate; x < (map.length - minCoordinate); x += size) {
for (int y = minCoordinate; y < (map.length - minCoordinate); y += size) {
int left = x - minCoordinate;
int right = x + minCoordinate;
int up = y - minCoordinate;
int down = y + minCoordinate;
// the four corner values
int val1 = map[left][up]; // upper left
int val2 = map[left][down]; // lower left
int val3 = map[right][up]; // upper right
int val4 = map[right][down];// lower right
calculateAndInsertAverage(val1, val2, val3, val4, variation,
map, x, y);
}
}
}
/**
* Calculates average values of four corner values taken from the smallest
* possible diamond. This method calculates the values for the even rows,
* starting with row 0.
*
* #param minCoordinate
* the x-coordinate of the first diamond center
* #param map
* the height map to fill
* #param size
* the length of the diagonals of the diamonds
* #param maxIndex
* the maximum index in the array
* #param variation
* the randomness in the height map
*/
private static void squareStepEven(int minCoordinate, int[][] map,
int size, int maxIndex, int variation) {
for (int x = minCoordinate; x < map.length; x += size) {
for (int y = 0; y < map.length; y += size) {
if (y == maxIndex) {
map[x][y] = map[x][0];
continue;
}
int left = x - minCoordinate;
int right = x + minCoordinate;
int down = y + minCoordinate;
int up = 0;
if (y == 0) {
up = maxIndex - minCoordinate;
} else {
up = y - minCoordinate;
}
// the four corner values
int val1 = map[left][y]; // left
int val2 = map[x][up]; // up
int val3 = map[right][y];// right
int val4 = map[x][down]; // down
calculateAndInsertAverage(val1, val2, val3, val4, variation,
map, x, y);
}
}
}
/**
* Calculates average values of four corner values taken from the smallest
* possible diamond. This method calculates the values for the odd rows,
* starting with row 1.
*
* #param minCoordinate
* the x-coordinate of the first diamond center
* #param map
* the height map to fill
* #param size
* the length of the diagonals of the diamonds
* #param maxIndex
* the maximum index in the array
* #param variation
* the randomness in the height map
*/
private static void squareStepOdd(int[][] map, int size, int minCoordinate,
int maxIndex, int variation) {
for (int x = 0; x < map.length; x += size) {
for (int y = minCoordinate; y < map.length; y += size) {
if (x == maxIndex) {
map[x][y] = map[0][y];
continue;
}
int left = 0;
int right = x + minCoordinate;
int down = y + minCoordinate;
int up = y - minCoordinate;
if (x == 0) {
left = maxIndex - minCoordinate;
} else {
left = x - minCoordinate;
}
// the four corner values
int val1 = map[left][y]; // left
int val2 = map[x][up]; // up
int val3 = map[right][y];// right
int val4 = map[x][down]; // down
calculateAndInsertAverage(val1, val2, val3, val4, variation,
map, x, y);
}
}
}
/**
* Calculates an average value, adds a variable amount to that value and
* inserts it into the height map.
*
* #param val1
* first of the values used to calculate the average
* #param val2
* second of the values used to calculate the average
* #param val3
* third of the values used to calculate the average
* #param val4
* fourth of the values used to calculate the average
* #param variation
* adds variation to the average value
* #param map
* the height map to fill
* #param x
* the x-coordinate of the place to fill
* #param y
* the y-coordinate of the place to fill
*/
private static void calculateAndInsertAverage(int val1, int val2, int val3,
int val4, int variation, int[][] map, int x, int y) {
int avg = (val1 + val2 + val3 + val4) >> 2;// average
int var = (int) ((Math.random() * ((variation << 1) + 1)) - variation);
map[x][y] = avg + var;
}
public static void main(String[] args) {
}
}
Handler.java
package com.game.main;
import java.awt.Graphics;
import java.util.LinkedList;
public class Handler {
LinkedList<GameObject> object = new LinkedList<GameObject>();
LinkedList<Tiles> tile = new LinkedList<Tiles>();
public void tick(){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.tick();
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.tick();
}
}
public void render(Graphics g){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.render(g);
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.render(g);
}
}
public void addObject(GameObject object){
this.object.add(object);
}
public void removeObject(GameObject object){
this.object.remove(object);
}
public void addObject(Tiles tile){
this.tile.add(tile);
}
public void removeObject(Tiles tile){
this.tile.remove(tile);
}
}
Tiles.java
package com.game.main;
import java.awt.Graphics;
import java.util.LinkedList;
public class Handler {
LinkedList<GameObject> object = new LinkedList<GameObject>();
LinkedList<Tiles> tile = new LinkedList<Tiles>();
public void tick(){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.tick();
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.tick();
}
}
public void render(Graphics g){
for (int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);
tempObject.render(g);
}
for (int t = 0; t < tile.size(); t++){
Tiles tempObject = tile.get(t);
tempObject.render(g);
}
}
public void addObject(GameObject object){
this.object.add(object);
}
public void removeObject(GameObject object){
this.object.remove(object);
}
public void addObject(Tiles tile){
this.tile.add(tile);
}
public void removeObject(Tiles tile){
this.tile.remove(tile);
}
}
TerrianTile.java
package com.game.main;
import java.awt.Color;
import java.awt.Graphics;
public class TerrianTile extends Tiles {
public TerrianTile(int x, int y, int tileType) {
super(x, y, tileType);
}
public void tick(){
}
public void render(Graphics g){
if (tileType <= 0){
g.setColor(Color.BLUE);
g.fillRect(x, y, 10, 10);
}
//water
if (tileType > 0 && tileType < 40){
g.setColor(Color.BLUE);
g.fillRect(x, y, 10, 10);
}
//sand
if (tileType >= 40 && tileType < 55){
g.setColor(Color.YELLOW);
g.fillRect(x, y, 10, 10);
}
//grass
if (tileType >= 55 && tileType < 120){
g.setColor(Color.GREEN);
g.fillRect(x, y, 10, 10);
}
//forest
if (tileType >= 120 && tileType < 140){
g.setColor(Color.LIGHT_GRAY);
g.fillRect(x, y, 10, 10);
}
//stone
if (tileType >= 140 && tileType < 170){
g.setColor(Color.GRAY);
g.fillRect(x, y, 10, 10);
}
//snow
if (tileType >= 170){
g.setColor(Color.WHITE);
g.fillRect(x, y, 10, 10);
}
}
}
KeyInput.java
package com.game.main;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyInput extends KeyAdapter{
private Handler handler;
public KeyInput(Handler handler){
this.handler = handler;
}
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ID.Player){
// key events for player 1
if (key == KeyEvent.VK_W) tempObject.setVelY(-5);
if (key == KeyEvent.VK_S) tempObject.setVelY(5);
if (key == KeyEvent.VK_D) tempObject.setVelX(5);
if (key == KeyEvent.VK_A) tempObject.setVelX(-5);
}
}
}
public void keyReleased(KeyEvent e){
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ID.Player){
// key events for player 1
if (key == KeyEvent.VK_W) tempObject.setVelY(0);
if (key == KeyEvent.VK_S) tempObject.setVelY(0);
if (key == KeyEvent.VK_D) tempObject.setVelX(0);
if (key == KeyEvent.VK_A) tempObject.setVelX(0);
}
}
}
}
Not sure if there is way to container the tiles in a rectangle and then move the rectangle. Any help would be much appreciated.
I dont really know what you mean by moving the tiles in a rectangle but if you just simply want to move all of them in a certain direction you could use g.translate(dx, dY) before you draw them.
Or if the terrain doesnt change you could draw them on an image at the beginning and then draw the image each frame at diffrent positions.
EDIT: updated code and question
I added main() method as stated in aswers but I still can't export it.
I am running my program as Java Applet, and apparently I need to use Java Application to run it standalone, but when I change run configuration to Application i get these errors:
Exception in thread "main" java.lang.NullPointerException
at acm.graphics.GImage.determineSize(GImage.java:564)
at acm.graphics.GImage.setImage(GImage.java:173)
at acm.graphics.GImage.<init>(GImage.java:115)
at acm.graphics.GImage.<init>(GImage.java:54)
at Pong.createTexture(Pong.java:160)
at Pong.run(Pong.java:81)
at Pong.main(Pong.java:55)
I need to export my project from Eclipse as a standalone runnable JAR, but when i go to export -> java -> JAR file i dont see any classes to select and im getting stuck at this (screen) window. I only have one class in my project.
This is not relevant anymore but I'll leave it here to keep edit history
import java.awt.Color;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.util.Random;
import acm.graphics.GImage;
import acm.graphics.GLabel;
import acm.graphics.GObject;
import acm.graphics.GOval;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
/* TO DO LIST
* ------------------
* Corner Bounce
*
*
*
*/
#SuppressWarnings("serial")
public class Pong extends GraphicsProgram {
public double mouseY;
private static final double PAUSE = 1000 / 96.0;
private Random rand = new Random();
private boolean AI_GODMODE = false;
// ball
public double startX;
public double startY;
private static final double BALL_SIZE = 20;
private static final double SPEED = 5;
private double ballHorizontalSpeed = SPEED * 1.5;
private double ballVerticalSpeed = SPEED;
// paddle
private static int HEIGHT = 150;
private static int WIDTH = 15;
private static int COUNTER = 0;
private static int AI_SPEED = 10; // AI difficulty 1-20
// label
public int AI_SCORE = 0;
public int PLAYER_SCORE = 0;
public int TOTAL_GAMES = 0;
private float TRANSPARENCY = 0.0f;
// counters
private static final int PADDING = 10;
private static final int MODIFIER = 3;
public static void main(String[] args) {
Pong p = new Pong();
p.run();
}
public void run() {
addMouseListeners();
// counters setup
GLabel counter = new GLabel(String.valueOf(COUNTER));
GLabel aiScore = new GLabel(String.valueOf(AI_SCORE));
GLabel average = new GLabel(String.valueOf("Avg: 0"));
GLabel playerScore = new GLabel(String.valueOf(COUNTER));
Color labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
Color scoreC = new Color(0, 0.0f, 0.0f, 0.1f);
counter.setFont("Impact-600");
aiScore.setFont("Impact-100");
average.setFont("Impact-50");
playerScore.setFont("Impact-100");
counter.setColor(labelC);
aiScore.setColor(scoreC);
playerScore.setColor(scoreC);
average.setColor(scoreC);
counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
getHeight() / 2 + counter.getHeight() / 3.2);
counter.sendToFront();
// make objects
GImage paddleLeftTexture = createTexture("texture.png", WIDTH + 1,
HEIGHT + 1);
GImage paddleRightTexture = createTexture("texture2.png", WIDTH + 1,
HEIGHT + 1);
GImage ballTexture = createTexture("ballTexture.png", (int) BALL_SIZE,
(int) BALL_SIZE);
GImage greenFlash = createTexture("greenFlash.png", 100, 300);
GImage blueFlash = createTexture("blueFlash.png", 100, 300);
GOval ball = makeBall();
GRect paddleLeft = makePaddle();
GRect paddleRight = makePaddle();
greenFlash.setLocation(-200, 0);
blueFlash.setLocation(-200, 0);
// generate GUI
drawGraphics(ball, paddleLeftTexture, paddleRightTexture, ballTexture,
greenFlash, blueFlash, counter, paddleLeft, paddleRight,
aiScore, playerScore, average);
// game start
bounce(labelC, aiScore, playerScore, counter, ball, paddleLeft,
paddleRight, paddleLeftTexture, paddleRightTexture,
ballTexture, greenFlash, blueFlash, average);
}
public void bounce(Color labelC, GLabel aiScore, GLabel playerScore,
GLabel counter, GOval ball, GRect paddleLeft, GRect paddleRight,
GImage paddleLeftTexture, GImage paddleRightTexture,
GImage ballTexture, GImage greenFlash, GImage blueFlash,
GLabel average) {
preGameSetup(ball, paddleRight, paddleRightTexture, counter);
updateAiScore(aiScore);
updatePlayerScore(playerScore);
updateAverage(average);
while (true) {
moveBall(ballHorizontalSpeed, ballVerticalSpeed, ball, ballTexture);
movePlayerPaddle(paddleLeft, paddleLeftTexture);
moveAiPaddle(ball, paddleRight, paddleRightTexture);
detectHit(ball, paddleRight, paddleLeft, counter, labelC);
if (TRANSPARENCY >= 0.0f) {
TRANSPARENCY -= TRANSPARENCY / 100f;
}
labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
counter.setColor(labelC);
if (detectBallOffScreen(ball)) {
ballOffScreen(ball, ballTexture, aiScore, playerScore,
greenFlash, blueFlash, average);
COUNTER = 0;
bounce(labelC, aiScore, playerScore, counter, ball, paddleLeft,
paddleRight, paddleLeftTexture, paddleRightTexture,
ballTexture, greenFlash, blueFlash, average);
}
pause(PAUSE);
}
}
public static GRect makePaddle() {
GRect result = new GRect(0, 0, WIDTH, HEIGHT);
result.setFilled(true);
result.setColor(Color.BLACK);
return result;
}
public static GOval makeBall() {
GOval result = new GOval(150, 100, BALL_SIZE, BALL_SIZE);
result.setFilled(true);
result.setColor(Color.WHITE);
return result;
}
private GImage createTexture(String importedImage, int width, int height) {
Image importResult = getImage(getCodeBase(), importedImage);
GImage textureResult = new GImage(importResult);
textureResult.setSize(width, height);
return textureResult;
}
public void mouseMoved(MouseEvent e) {
mouseY = e.getY();
}
private boolean ballHitBottom(GOval ball) {
double bottomY = ball.getY() + ball.getHeight();
return bottomY >= getHeight();
}
private boolean ballHitTop(GOval ball) {
double topY = ball.getY();
return topY <= 0;
}
private boolean ballHitPaddleRight(GOval ball, GRect paddle) {
double rightX = ball.getX() + ball.getWidth();
double rightY = ball.getY() + ball.getHeight() / 2;
double paddlePosX = paddle.getX();
double paddlePosY = paddle.getY();
if (rightX >= paddlePosX && rightY >= paddlePosY
&& rightY <= paddlePosY + paddle.getHeight())
return true;
else
return false;
}
private boolean detectBallOffScreen(GOval ball) {
if (ball.getX() < 2 * WIDTH - BALL_SIZE
|| ball.getX() > getWidth() - 2 * WIDTH)
return true;
else
return false;
}
private boolean ballHitPaddleLeft(GOval ball, GRect paddle) {
double leftX = ball.getX();
double leftY = ball.getY();
double paddlePosX = paddle.getX() + WIDTH;
double paddlePosY = paddle.getY();
if (leftX <= paddlePosX && leftY >= paddlePosY
&& leftY <= paddlePosY + paddle.getHeight())
return true;
else
return false;
}
/*
* private boolean ballHitPaddleBorder(GOval ball, GRect paddle) { ; if
* (ball.getX() > paddle.getX() - BALL_SIZE && ball.getX() < paddle.getX() +
* WIDTH && ball.getY() > paddle.getY() && ball.getY() < paddle.getY() +
* ballVerticalSpeed) return true; else if (ball.getX() > paddle.getX() -
* BALL_SIZE && ball.getX() < paddle.getX() + WIDTH && ball.getY() >
* paddle.getY() + HEIGHT && ball.getY() < paddle.getY() + HEIGHT -
* ballVerticalSpeed) return true; else return false; }
*/
private void preGameSetup(GObject ball, GObject paddleRight,
GObject paddleRightTexture, GLabel counter) {
startX = rand.nextInt((int) (getWidth() * 0.8))
+ (int) (0.1 * getWidth()); // zapobiega pojawieniu się piłki po
// lewej stronie lewej paletki
startY = rand.nextInt(getHeight());
ball.setLocation(startX, startY);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH, startY
- HEIGHT / 2);
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH, startY - HEIGHT
/ 2);
paddleRightTexture.sendToFront();
counter.setLabel(String.valueOf(COUNTER));
counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
getHeight() / 2 + counter.getHeight() / 3.2);
ballHorizontalSpeed = SPEED * 1.5;
ballVerticalSpeed = SPEED;
}
private void updateAiScore(GLabel aiScore) {
aiScore.setLabel(String.valueOf(AI_SCORE));
aiScore.setLocation(getWidth() - aiScore.getWidth() - MODIFIER * WIDTH
- PADDING, getHeight() - PADDING);
}
private void updatePlayerScore(GLabel playerScore) {
playerScore.setLabel(String.valueOf(PLAYER_SCORE));
playerScore.setLocation(MODIFIER * WIDTH + PADDING, getHeight()
- PADDING);
}
private void updateScore(GLabel counter, Color labelC) {
counter.setLabel(String.valueOf(COUNTER));
counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
getHeight() / 2 + counter.getHeight() / 3.2);
TRANSPARENCY = 0.1f;
labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
counter.setColor(labelC);
}
private void updateAverage(GLabel average) {
if (TOTAL_GAMES == 0) {
average.setLabel("Round: 1 Avg: 0");
} else {
average.setLabel("Round: " + String.valueOf(TOTAL_GAMES + 1) + " Avg: "
+ String.valueOf((int) ((AI_SCORE + PLAYER_SCORE) / TOTAL_GAMES)));}
average.setLocation(getWidth() / 2 - average.getWidth() / 2,
getHeight() - PADDING);
}
private void drawGraphics(GObject ball, GObject paddleLeftTexture,
GObject paddleRightTexture, GObject ballTexture,
GObject greenFlash, GObject blueFlash, GObject counter,
GObject paddleLeft, GObject paddleRight, GObject aiScore,
GObject playerScore, GLabel average) {
add(ball);
add(paddleLeftTexture);
add(paddleRightTexture);
add(ballTexture);
add(greenFlash);
add(blueFlash);
add(counter);
add(paddleLeft);
add(paddleRight);
add(aiScore);
add(playerScore);
add(average);
}
private void detectHit(GOval ball, GRect paddleRight, GRect paddleLeft,
GLabel counter, Color labelC) {
if (ballHitBottom(ball) && ballVerticalSpeed >= 0) {
ballVerticalSpeed *= -1;
}
if (ballHitTop(ball) && ballVerticalSpeed <= 0) {
ballVerticalSpeed *= -1;
}
if (ballHitPaddleRight(ball, paddleRight)) {
ballHorizontalSpeed *= -1;
}
if (ballHitPaddleLeft(ball, paddleLeft)) {
ballHorizontalSpeed *= -1;
COUNTER++;
updateScore(counter, labelC);
boolean bool = rand.nextBoolean();
if (bool)
if (ballHorizontalSpeed > 0)
ballHorizontalSpeed += 1;
else
ballHorizontalSpeed -= 1;
else if (ballVerticalSpeed > 0)
ballVerticalSpeed += 0.5;
else
ballVerticalSpeed -= 0.5;
}
/*
* if(ballHitPaddleBorder(ball, paddleLeft)){ ballVerticalSpeed *= -1; }
*
* if(ballHitPaddleBorder(ball, paddleRight)){ ballVerticalSpeed *= -1;
* }
*/
}
private void ballOffScreen(GOval ball, GObject ballTexture, GLabel aiScore,
GLabel playerScore, GObject greenFlash, GObject blueFlash,
GLabel average) {
if (ball.getX() < 2 * WIDTH - BALL_SIZE) { // left
double pos = ball.getY() - greenFlash.getHeight() / 2;
ballTexture.move(-ballTexture.getWidth() * 2, 0);
AI_SCORE += COUNTER;
TOTAL_GAMES++;
updateAiScore(aiScore);
updateAverage(average);
for (int i = 20; i < 100; i += 5) {
greenFlash.setLocation(-i, pos);
pause(25);
}
} else { // right
double pos = ball.getY() - blueFlash.getHeight() / 2;
ballTexture.move(ballTexture.getWidth() * 2, 0);
PLAYER_SCORE += COUNTER;
TOTAL_GAMES++;
updatePlayerScore(playerScore);
updateAverage(average);
for (int i = 20; i < 100; i += 5) {
blueFlash.setLocation(getWidth() - blueFlash.getWidth() + i,
pos);
pause(25);
}
}
}
private void moveBall(double ballHorizontalSpeed, double ballVerticalSpeed,
GObject ball, GObject ballTexture) {
ball.move(ballHorizontalSpeed, ballVerticalSpeed);
ballTexture.setLocation(ball.getX(), ball.getY());
ballTexture.sendToFront();
}
private void movePlayerPaddle(GObject paddleLeft, GObject paddleLeftTexture) {
if (mouseY < getHeight() - HEIGHT) { // Player
paddleLeft.setLocation(2 * WIDTH, mouseY);
paddleLeftTexture.setLocation(2 * WIDTH, mouseY);
paddleLeftTexture.sendToFront();
} else {
paddleLeft.setLocation(2 * WIDTH, getHeight() - HEIGHT);
paddleLeftTexture.setLocation(2 * WIDTH, getHeight() - HEIGHT);
paddleLeftTexture.sendToFront();
}
}
private void moveAiPaddle(GOval ball, GRect paddleRight,
GImage paddleRightTexture) {
if (AI_GODMODE == true) { // modeSelector
if (ball.getY() < getHeight() - HEIGHT / 2
&& ball.getY() > HEIGHT / 2) {
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH,
ball.getY() - HEIGHT / 2);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
ball.getY() - HEIGHT / 2);
paddleRightTexture.sendToFront();
} else if (ball.getY() <= HEIGHT / 2) {
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH, 0);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
-0);
paddleRightTexture.sendToFront();
} else {
paddleRight.setLocation(getWidth() - MODIFIER * WIDTH,
getHeight() - HEIGHT);
paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
getHeight() - HEIGHT);
paddleRightTexture.sendToFront();
}
} else { // end godMode if
double targetY = ball.getY() + BALL_SIZE / 2;
if (targetY < getHeight() - HEIGHT / 2 && targetY > HEIGHT / 2) {
if (targetY < paddleRight.getY() + HEIGHT / 2) {
paddleRight.move(0, -AI_SPEED);
paddleRightTexture.move(0, -AI_SPEED);
} else if (targetY > paddleRight.getY() + HEIGHT / 2) {
paddleRight.move(0, AI_SPEED);
paddleRightTexture.move(0, AI_SPEED);
}
} // end normalMode if
} // end modeSelector if
} // end moveAiPaddle void
} // end class
Judging from the linked image, your class Pong does not have a main method. It simply cant be exported as a runnable jar file, because you could never run it. Add a main method, or export to a standard java jar file (File -> Export -> Java -> JAR file). The jar file it produces using the latter method will NOT be runnable if there is no main method, period. You have to have a main method in order to run this code stand alone, because that is the entry point for the application.
Per your comment, You will need to create an instance of the Pong class inside of the main method and invoke its run() method:
public static void main(String[] args) {
Pong p = new Pong();
p.run();
}
If the run method of the Pong class is static, you wont need an instance, and you could do this:
public static void main(String[] args) {
Pong.run();
}
You should be exporting it as a "Runnable JAR file" instead of a "JAR file". Once you choose this you should be able to use a drop down menu called "Launch configuration:", and then you can choose your export destination.
I am using Eclipse Kepler. It may not be the same for different versions.
Your project should contain class with main method so that you can see your project in Launch Configuration drop down list. (Eclipse Kepler)