Add second year
@ -0,0 +1,56 @@
|
||||
// package MyApplication;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
public class MyApplication extends JFrame {
|
||||
private static final Dimension WindowSize = new Dimension(600,600);
|
||||
|
||||
public MyApplication() {
|
||||
// create & set up the window
|
||||
this.setTitle("Pacman, or something...");
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2;
|
||||
int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MyApplication w = new MyApplication();
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
int height = 50, width = 50; // defining the height & width of the rectangle
|
||||
int x = 10, y = 10; // defining the vertical & horizontal position between rectangles
|
||||
|
||||
// looping for each of the 10 rows in the window
|
||||
for (int row = 0; row < 10; row++) {
|
||||
|
||||
// looping for each of the 10 columns in the window
|
||||
for (int column = 0; column < 10; column++) {
|
||||
|
||||
// randomly generating an RGB colour & setting the graphic to use it
|
||||
Color c = new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255));
|
||||
g.setColor(c);
|
||||
|
||||
// make a filled rectangle with the specified dimensions at the specified x, y co-ordinates
|
||||
g.fillRect(x, y, height, width);
|
||||
|
||||
|
||||
// increasing the x by adding the size of a square plus the desired padding
|
||||
x += width + 10;
|
||||
}
|
||||
|
||||
// resetting the x value to 10 for the next row
|
||||
x = 10;
|
||||
|
||||
// increasing the y by adding the height of a square plus the desired padding
|
||||
y += height + 10;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
public class GameObject {
|
||||
// member data
|
||||
private int x, y;
|
||||
private int height = 50, width = 50;
|
||||
private Color c;
|
||||
private int stepSize = 10; // how many pixels the object will move at a time
|
||||
|
||||
// constructor
|
||||
public GameObject() {
|
||||
// randomly generating colour
|
||||
c = new Color((int)(Math.random()*255), (int)(Math.random()*255), (int)(Math.random()*255));
|
||||
|
||||
// randomly generating initial x y co-ordinates
|
||||
x = (int)(Math.random()*600);
|
||||
y = (int)(Math.random()*600);
|
||||
}
|
||||
|
||||
// public interface
|
||||
public void move() {
|
||||
// generating either a 1 or a 0 to determine if the square should move left or right and up or down - 1 = left/up, 0 = right/down
|
||||
int xDirection = (int)(Math.random()*2);
|
||||
int yDirection = (int)(Math.random()*2);
|
||||
|
||||
// changing the x & y co-ordinates by either plus or minus the stepSize, depending on the direction
|
||||
x += (xDirection == 1) ? -stepSize : + stepSize;
|
||||
y += (yDirection == 1) ? -stepSize : + stepSize;
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
// setting colour
|
||||
g.setColor(c);
|
||||
|
||||
// make a filled rectangle with the specified dimensions at the specified x, y co-ordinates
|
||||
g.fillRect(x, y, height, width);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MovingSquaresApplication extends JFrame implements Runnable {
|
||||
// window dimensions
|
||||
private static final Dimension WindowSize = new Dimension(600,600);
|
||||
|
||||
// array of gameobjects (squares)
|
||||
private GameObject gameobjects[] = new GameObject[100];
|
||||
|
||||
// constructor
|
||||
public MovingSquaresApplication() {
|
||||
// create & set up the window
|
||||
this.setTitle("Moving Squares Apllication");
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2;
|
||||
int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
setVisible(true);
|
||||
|
||||
// create array of game objects.
|
||||
//Arrays.fill(gameobjects, 100);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
gameobjects[i] = new GameObject();
|
||||
}
|
||||
|
||||
// creating a new thread & starting it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
}
|
||||
|
||||
// run method called by thread
|
||||
public void run() {
|
||||
while (true) {
|
||||
// iterating over array of gameobjects & calling move() on each object
|
||||
for (GameObject go : gameobjects) {
|
||||
go.move();
|
||||
}
|
||||
|
||||
try {
|
||||
// sleeping
|
||||
Thread.sleep(100);
|
||||
|
||||
// catching exception
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// repainting now that every object has been moved
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// paint method
|
||||
public void paint(Graphics g) {
|
||||
// filling the screen with a white square between "frames" of animation to get rid of trails caused by moving objects
|
||||
Color c = new Color(255, 255, 255);
|
||||
g.setColor(c);
|
||||
g.fillRect(0, 0, 1000, 1000);
|
||||
|
||||
// iterating over each GameObject and calling paint on it
|
||||
for (GameObject go : gameobjects) {
|
||||
go.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// instantiating class in main method to begin application
|
||||
MovingSquaresApplication w = new MovingSquaresApplication();
|
||||
}
|
||||
}
|
22
second/semester2/CT255/Assignments/Assigment-03/Alien.java
Normal file
@ -0,0 +1,22 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Alien extends Sprite2D {
|
||||
private int stepSize = 5;
|
||||
|
||||
public Alien(Image image) {
|
||||
super(image);
|
||||
}
|
||||
|
||||
// method to randomly move the alien
|
||||
public void move() {
|
||||
// generating either a 1 or a 0 to determine if the square should move left or right and up or down - 1 = left/up, 0 = right/down
|
||||
int xDirection = (int)(Math.random()*2);
|
||||
int yDirection = (int)(Math.random()*2);
|
||||
|
||||
// changing the x & y co-ordinates (inherited from superclass) by either plus or minus the stepSize, depending on the direction
|
||||
x += (xDirection == 1) ? -stepSize : + stepSize;
|
||||
y += (yDirection == 1) ? -stepSize : + stepSize;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class InvadersApplication extends JFrame implements Runnable, KeyListener {
|
||||
// member data
|
||||
private static String workingDirectory = System.getProperty("user.dir");
|
||||
|
||||
private Image alienImage;
|
||||
private Image playerImage;
|
||||
|
||||
private static final Dimension WindowSize = new Dimension(600, 600);
|
||||
private static final int NUMALIENS = 30;
|
||||
private Alien[] AliensArray = new Alien[NUMALIENS];
|
||||
private Player player;
|
||||
|
||||
// variable to hold how far the player should be moving in the x axis per frame - default 0.
|
||||
private int dx = 0;
|
||||
|
||||
// constructor
|
||||
public InvadersApplication() {
|
||||
// set up window
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
|
||||
// adding a key listener
|
||||
addKeyListener(this);
|
||||
|
||||
// load image from disk
|
||||
ImageIcon alienIcon = new ImageIcon(workingDirectory + "/alien_ship_1.png");
|
||||
ImageIcon playerIcon = new ImageIcon(workingDirectory + "/player_ship.png");
|
||||
|
||||
alienImage = alienIcon.getImage();
|
||||
playerImage = playerIcon.getImage();
|
||||
|
||||
// instantiating an alien for each index in the aliens array
|
||||
for (int i = 0; i < NUMALIENS; i++) {
|
||||
AliensArray[i] = new Alien(alienImage);
|
||||
|
||||
// generating a random starting position for the alien
|
||||
AliensArray[i].setPosition((int) (Math.random()*600), (int) (Math.random()*600));
|
||||
}
|
||||
|
||||
// creating a player icon & setting it's position
|
||||
player = new Player(playerImage);
|
||||
player.setPosition(270, 550);
|
||||
|
||||
setVisible(true);
|
||||
|
||||
// create a new thread & start it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
}
|
||||
|
||||
// thread's entry point
|
||||
public void run() {
|
||||
while (true) {
|
||||
// repainting
|
||||
this.repaint();
|
||||
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// getting the keycode of the event
|
||||
int key = e.getKeyCode();
|
||||
|
||||
// if right key pressed, making the distance to be moved 10px to the right
|
||||
if (key == KeyEvent.VK_RIGHT) {
|
||||
dx = 5;
|
||||
}
|
||||
// if left key pressed, making the distance to be moved 10px to the left
|
||||
if (key == KeyEvent.VK_LEFT) {
|
||||
dx = -5;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
// getting the keycode of the event
|
||||
int key = e.getKeyCode();
|
||||
|
||||
// if the key released was the left or right arrow, setting dx back to 0
|
||||
if (key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
|
||||
dx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
// application's paint method
|
||||
public void paint(Graphics g) {
|
||||
// draw a black rectangle on the whole canvas
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0, 0, 600, 600);
|
||||
|
||||
// iterating through each sprite, moving it, and calling it's paint method
|
||||
for (Alien a : AliensArray) {
|
||||
a.move();
|
||||
a.paint(g);
|
||||
}
|
||||
|
||||
// moving the player dx pixels - should be 0 if no key is being pressed
|
||||
player.move(dx);
|
||||
|
||||
// calling the Player's paint method
|
||||
player.paint(g);
|
||||
}
|
||||
|
||||
// application entry point
|
||||
public static void main(String[] args) {
|
||||
InvadersApplication ia = new InvadersApplication();
|
||||
}
|
||||
}
|
13
second/semester2/CT255/Assignments/Assigment-03/Player.java
Normal file
@ -0,0 +1,13 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Player extends Sprite2D {
|
||||
public Player(Image image) {
|
||||
super(image);
|
||||
}
|
||||
|
||||
// method to move the player by the supplied distance
|
||||
public void move(int distance) {
|
||||
x += distance; // x is inherited from the Sprite2D superclass
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Sprite2D {
|
||||
// member data
|
||||
public int x,y; // public so that it can be inherited
|
||||
private Image image;
|
||||
|
||||
public Sprite2D(Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
// paint method
|
||||
public void paint(Graphics g) {
|
||||
// draw the image
|
||||
g.drawImage(image, x, y, null);
|
||||
}
|
||||
|
||||
// set the position of the object
|
||||
public void setPosition(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
BIN
second/semester2/CT255/Assignments/Assigment-03/alien_ship_1.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
second/semester2/CT255/Assignments/Assigment-03/player_ship.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
31
second/semester2/CT255/Assignments/Assigment-04/Alien.java
Normal file
@ -0,0 +1,31 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Alien extends Sprite2D {
|
||||
private int stepSize = 2;
|
||||
|
||||
public Alien(Image image) {
|
||||
super(image);
|
||||
}
|
||||
|
||||
// method to randomly move the alien
|
||||
public void move(boolean right) {
|
||||
// changing the x & y co-ordinates (inherited from superclass) by either plus or minus the stepSize, depending on the direction
|
||||
if (right) {
|
||||
x += stepSize;
|
||||
}
|
||||
else {
|
||||
x -= stepSize;
|
||||
}
|
||||
}
|
||||
|
||||
// method to move aliend down
|
||||
public void moveDown() {
|
||||
y += 10;
|
||||
}
|
||||
|
||||
// getter method for the alien's x coordinate
|
||||
public int getx() {
|
||||
return x;
|
||||
}
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
public class InvadersApplication extends JFrame implements Runnable, KeyListener {
|
||||
// member data
|
||||
private static String workingDirectory = System.getProperty("user.dir");
|
||||
|
||||
private Image alienImage;
|
||||
private Image playerImage;
|
||||
|
||||
private static final Dimension WindowSize = new Dimension(800, 600);
|
||||
private static final int NUMALIENS = 30;
|
||||
private Alien[] AliensArray = new Alien[NUMALIENS];
|
||||
boolean right = true; // boolean to tell which direction the aliens are moving
|
||||
private Player player;
|
||||
|
||||
private BufferStrategy strategy;
|
||||
|
||||
// variable to hold how far the player should be moving in the x axis per frame - default 0.
|
||||
private int dx = 0;
|
||||
|
||||
// constructor
|
||||
public InvadersApplication() {
|
||||
// set up window
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// adding a key listener
|
||||
addKeyListener(this);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
|
||||
// load image from disk
|
||||
ImageIcon alienIcon = new ImageIcon(workingDirectory + "/alien_ship_1.png");
|
||||
ImageIcon playerIcon = new ImageIcon(workingDirectory + "/player_ship.png");
|
||||
|
||||
alienImage = alienIcon.getImage();
|
||||
playerImage = playerIcon.getImage();
|
||||
|
||||
// initial x and y coordinates for the aliens
|
||||
int alienx = 200;
|
||||
int alieny = 25;
|
||||
int column = 0; // keeps track of which column the alien is in
|
||||
for (int i = 0; i < NUMALIENS; i++) {
|
||||
AliensArray[i] = new Alien(alienImage);
|
||||
AliensArray[i].setPosition(alienx, alieny);
|
||||
|
||||
alienx += 60;
|
||||
column++;
|
||||
|
||||
// go onto a new line every 5 aliens
|
||||
if (column >= 6) {
|
||||
column = 0;
|
||||
alienx = 200;
|
||||
alieny += 60;
|
||||
}
|
||||
}
|
||||
|
||||
// creating a player icon & setting it's position
|
||||
player = new Player(playerImage);
|
||||
player.setPosition(270, 550);
|
||||
|
||||
setVisible(true);
|
||||
|
||||
createBufferStrategy(2);
|
||||
strategy = getBufferStrategy();
|
||||
|
||||
// create a new thread & start it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
}
|
||||
|
||||
// thread's entry point
|
||||
public void run() {
|
||||
while (true) {
|
||||
// repainting
|
||||
this.repaint();
|
||||
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// getting the keycode of the event
|
||||
int key = e.getKeyCode();
|
||||
|
||||
// if right key pressed, making the distance to be moved 10px to the right
|
||||
if (key == KeyEvent.VK_RIGHT) {
|
||||
dx = 5;
|
||||
}
|
||||
// if left key pressed, making the distance to be moved 10px to the left
|
||||
if (key == KeyEvent.VK_LEFT) {
|
||||
dx = -5;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
// getting the keycode of the event
|
||||
int key = e.getKeyCode();
|
||||
|
||||
// if the key released was the left or right arrow, setting dx back to 0
|
||||
if (key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
|
||||
dx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
// application's paint method
|
||||
public void paint(Graphics g) {
|
||||
g = strategy.getDrawGraphics();
|
||||
// draw a black rectangle on the whole canvas
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0, 0, 800, 600);
|
||||
|
||||
|
||||
// iterating through each sprite, moving it, and calling it's paint method
|
||||
for (Alien a : AliensArray) {
|
||||
a.move(right);
|
||||
a.paint(g);
|
||||
}
|
||||
|
||||
// checking if any of the aliens hit the edge when they were moved
|
||||
for (Alien a : AliensArray) {
|
||||
// changing direction & moving down if edge is hit
|
||||
if (a.getx() > 750) {
|
||||
right = false;
|
||||
|
||||
// looping through all the aliens and moving them down
|
||||
for (Alien alien : AliensArray) {
|
||||
alien.moveDown();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (a.getx() < 0) {
|
||||
right = true;
|
||||
|
||||
// looping through all the aliens and moving them down
|
||||
for (Alien alien : AliensArray) {
|
||||
alien.moveDown();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// moving the player dx pixels - should be 0 if no key is being pressed
|
||||
player.move(dx);
|
||||
|
||||
// calling the Player's paint method
|
||||
player.paint(g);
|
||||
|
||||
strategy.show();
|
||||
}
|
||||
|
||||
// application entry point
|
||||
public static void main(String[] args) {
|
||||
InvadersApplication ia = new InvadersApplication();
|
||||
}
|
||||
}
|
13
second/semester2/CT255/Assignments/Assigment-04/Player.java
Normal file
@ -0,0 +1,13 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Player extends Sprite2D {
|
||||
public Player(Image image) {
|
||||
super(image);
|
||||
}
|
||||
|
||||
// method to move the player by the supplied distance
|
||||
public void move(int distance) {
|
||||
x += distance; // x is inherited from the Sprite2D superclass
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Sprite2D {
|
||||
// member data
|
||||
protected int x,y;
|
||||
private Image image;
|
||||
|
||||
public Sprite2D(Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
// paint method
|
||||
public void paint(Graphics g) {
|
||||
// draw the image
|
||||
g.drawImage(image, x, y, null);
|
||||
}
|
||||
|
||||
// set the position of the object
|
||||
public void setPosition(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y; }
|
||||
}
|
BIN
second/semester2/CT255/Assignments/Assigment-04/alien_ship_1.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
second/semester2/CT255/Assignments/Assigment-04/player_ship.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
55
second/semester2/CT255/Assignments/Assigment-05/Alien.java
Normal file
@ -0,0 +1,55 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Alien extends Sprite2D {
|
||||
public static long framesDrawn = 0; // variable to hold the number of frames drawn
|
||||
public static int aliensKilled = 0; // static variable to hold the count of the aliens killed - in alien class as it's intended to be modified by aliens
|
||||
public static int stepSize = 0; // how far the aliens move each frame - 0 by default but will get increased to 5 immediately
|
||||
private Image altImage;
|
||||
|
||||
public Alien(Image image, Image altImage) {
|
||||
super(image);
|
||||
this.altImage = altImage;
|
||||
}
|
||||
|
||||
// method to randomly move the alien
|
||||
public void move(boolean right) {
|
||||
// changing the x & y co-ordinates (inherited from superclass) by either plus or minus the stepSize, depending on the direction
|
||||
if (right) {
|
||||
x += stepSize;
|
||||
}
|
||||
else {
|
||||
x -= stepSize;
|
||||
}
|
||||
}
|
||||
|
||||
// method to move aliend down
|
||||
public void moveDown() {
|
||||
y += 25;
|
||||
}
|
||||
|
||||
// overridden paint method to allow animation
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
framesDrawn++;
|
||||
|
||||
if (framesDrawn % 100 < 50) {
|
||||
g.drawImage(image, x, y, null);
|
||||
}
|
||||
else {
|
||||
g.drawImage(altImage, x, y, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// overridden kill method to set isAlive to false and increment the aliensKilled counter
|
||||
public void kill() {
|
||||
isAlive = false;
|
||||
aliensKilled++;
|
||||
}
|
||||
|
||||
// method to increase the stepsize of the aliens
|
||||
public static void speedUp() {
|
||||
stepSize = stepSize + 3;
|
||||
}
|
||||
}
|
@ -0,0 +1,315 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.*;
|
||||
|
||||
public class InvadersApplication extends JFrame implements Runnable, KeyListener {
|
||||
// member data
|
||||
private static String workingDirectory = System.getProperty("user.dir");
|
||||
private static boolean isGraphicsInitialised = false;
|
||||
|
||||
private Image alienImage;
|
||||
private Image altAlienImage;
|
||||
private Image playerImage;
|
||||
private Image bulletImage;
|
||||
|
||||
private static final Dimension WindowSize = new Dimension(800, 600);
|
||||
|
||||
private static final int NUMALIENS = 30;
|
||||
private Alien[] aliensArray = new Alien[NUMALIENS]; // arraylist of all the currently extant bullets
|
||||
private ArrayList<PlayerBullet> bullets = new ArrayList<PlayerBullet>();
|
||||
|
||||
boolean right = true; // boolean to tell which direction the aliens are moving
|
||||
private Player player;
|
||||
|
||||
private BufferStrategy strategy;
|
||||
|
||||
// variable to hold how far the player should be moving in the x axis per frame - default 0.
|
||||
private int dx = 0;
|
||||
|
||||
public boolean gameOver = false; // boolean to tell what state the game is in
|
||||
private long score = 0; // player's score
|
||||
private long bestScore = 0; // the best score the player has achieved
|
||||
|
||||
// constructor
|
||||
public InvadersApplication() {
|
||||
// set up window
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// adding a key listener
|
||||
addKeyListener(this);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
|
||||
// load image from disk
|
||||
ImageIcon alienIcon = new ImageIcon(workingDirectory + "/alien_ship_1.png");
|
||||
ImageIcon altAlienIcon = new ImageIcon(workingDirectory + "/alien_ship_2.png");
|
||||
ImageIcon playerIcon = new ImageIcon(workingDirectory + "/player_ship.png");
|
||||
ImageIcon bulletIcon = new ImageIcon(workingDirectory + "/bullet.png");
|
||||
|
||||
alienImage = alienIcon.getImage();
|
||||
altAlienImage = altAlienIcon.getImage();
|
||||
playerImage = playerIcon.getImage();
|
||||
bulletImage = bulletIcon.getImage();
|
||||
|
||||
// creating a player icon & setting it's position
|
||||
player = new Player(playerImage);
|
||||
player.setPosition(270, 550);
|
||||
|
||||
setVisible(true);
|
||||
|
||||
createBufferStrategy(2);
|
||||
strategy = getBufferStrategy();
|
||||
|
||||
// create a new thread & start it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
|
||||
isGraphicsInitialised = true;
|
||||
}
|
||||
|
||||
// thread's entry point
|
||||
public void run() {
|
||||
while (true) {
|
||||
// repainting
|
||||
try {
|
||||
this.repaint();
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// what to do on keypress if the player is alive (game is being played)
|
||||
if (player.isAlive) {
|
||||
// getting the keycode of the event
|
||||
int key = e.getKeyCode();
|
||||
|
||||
// if right key pressed, making the distance to be moved 10px to the right
|
||||
if (key == KeyEvent.VK_RIGHT) {
|
||||
dx = 5;
|
||||
}
|
||||
// if left key pressed, making the distance to be moved 10px to the left
|
||||
if (key == KeyEvent.VK_LEFT) {
|
||||
dx = -5;
|
||||
}
|
||||
}
|
||||
// what to do on keypress if the player is not alive (game is over)
|
||||
else {
|
||||
// resetting everything so that the game can be restarted
|
||||
resetAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
// getting the keycode of the event
|
||||
int key = e.getKeyCode();
|
||||
|
||||
// if the key released was the left or right arrow, setting dx back to 0
|
||||
if (key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_LEFT) {
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
// if space key released "firing" a bullet (creating one)
|
||||
if (key == KeyEvent.VK_SPACE) { // firing bullets on release so that the player can't just hold down space to fire
|
||||
bullets.add(new PlayerBullet(player, bulletImage));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
// method to reset everything so that a new game may be started
|
||||
public void resetAll() {
|
||||
Alien.framesDrawn = 0;
|
||||
Alien.aliensKilled = 0;
|
||||
Alien.stepSize = 0;
|
||||
newWave();
|
||||
//aliensArray = null;
|
||||
|
||||
player.setPosition(270, 550);
|
||||
player.isAlive = true;
|
||||
}
|
||||
|
||||
// gameplay method
|
||||
public void gameplay(Graphics g) {
|
||||
// checking if any of the aliens hit the edge when they were moved
|
||||
for (Alien a : aliensArray) {
|
||||
// changing direction & moving down if edge is hit
|
||||
if (a.getX() > 750) {
|
||||
right = false;
|
||||
|
||||
// looping through all the aliens and moving them down
|
||||
for (Alien alien : aliensArray) {
|
||||
alien.moveDown();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (a.getX() < 0) {
|
||||
right = true;
|
||||
|
||||
// looping through all the aliens and moving them down
|
||||
for (Alien alien : aliensArray) {
|
||||
alien.moveDown();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// looping through each bullet, moving it, and calling its paint method if it has not collided, removing it and the alien it collided with if it has
|
||||
// using an iterator so that bullets can be removed from the list as we loop through
|
||||
Iterator bulletsIterator = bullets.iterator();
|
||||
while (bulletsIterator.hasNext()) {
|
||||
PlayerBullet b = (PlayerBullet) bulletsIterator.next();
|
||||
b.move();
|
||||
|
||||
// bullets will be removed to save memory, but aliens will not be removed until a wave is over to preserve correct movement
|
||||
for (Alien a : aliensArray) {
|
||||
// only checking for collisions if the alien is alive
|
||||
if (a.isAlive) {
|
||||
// if the bullet collides with an alien, removing the bullet & hiding the alien
|
||||
// the aliens dimensions are 50x32
|
||||
// the bullets dimensions are 6x16
|
||||
if (
|
||||
( (a.getX() < b.getX() && a.getX()+50 > b.getX()) || (b.getX() < a.getX() && b.getX()+6 > a.getX()) ) &&
|
||||
( (a.getY() < b.getY() && a.getY()+32 > b.getY()) || (b.getY() < a.getY() && b.getY()+16 > a.getY()))
|
||||
) {
|
||||
bulletsIterator.remove();
|
||||
a.kill();
|
||||
score = score + 10; // increasing the score once the alien is killed
|
||||
b.kill(); // "killing" the bullet so it's not painted before it's been removed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// painting the bullet if it is "alive"
|
||||
if (b.isAlive) {
|
||||
b.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
// looping through each alien to see if it has collided with the player
|
||||
for (Alien a : aliensArray) {
|
||||
// checking to see if any of the (alive) aliens have collided with the player
|
||||
if (a.isAlive) {
|
||||
if (
|
||||
// the player's dimensions are 54 x 32
|
||||
( (a.getX() < player.getX() && a.getX()+50 > player.getX()) || (player.getX() < a.getX() && player.getX()+54 > a.getX()) )
|
||||
&&
|
||||
( (a.getY() < player.getY() && a.getY()+32 > player.getY()) || (player.getY() < a.getY() && player.getY()+32 > a.getY()))
|
||||
) {
|
||||
player.kill(); // "killing" the player
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// moving the player dx pixels - should be 0 if no key is being pressed
|
||||
player.move(dx);
|
||||
|
||||
// iterating through each sprite, moving it, and calling its paint method
|
||||
for (Alien a : aliensArray) {
|
||||
a.move(right);
|
||||
|
||||
// only painting the alien if it is alive
|
||||
if (a.isAlive) {
|
||||
a.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
// calling the Player's paint method
|
||||
player.paint(g);
|
||||
}
|
||||
|
||||
// application's paint method
|
||||
public void paint(Graphics g) {
|
||||
// making sure that the graphics are initialised before painting
|
||||
if (isGraphicsInitialised) {
|
||||
g = strategy.getDrawGraphics();
|
||||
// draw a black rectangle on the whole canvas
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0, 0, 800, 600);
|
||||
Font f = new Font("Times", Font.PLAIN, 50);
|
||||
g.setColor(Color.WHITE);
|
||||
|
||||
// calculating score
|
||||
score = Alien.aliensKilled * 10;
|
||||
|
||||
// displaying score and best score
|
||||
String scorebar = "Score: " + score + " Best: " + bestScore;
|
||||
g.drawString(scorebar, 50, 50);
|
||||
|
||||
|
||||
// if the game is not over, playing the game. else, displaying a gameover screen.
|
||||
if (player.isAlive) {
|
||||
// checking if all the aliens are dead, and if so, spawning a new wave
|
||||
boolean noAliens = true;
|
||||
for (Alien a : aliensArray) {
|
||||
if (a != null && a.isAlive) {
|
||||
noAliens = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (noAliens) {
|
||||
newWave();
|
||||
}
|
||||
gameplay(g);
|
||||
}
|
||||
else {
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
}
|
||||
String scores = "Score: " + score + " Best Score: " + bestScore;
|
||||
g.drawString("GAME OVER", 400, 300);
|
||||
g.drawString(scores, 400, 350);
|
||||
g.drawString("Press any key to continue", 400, 400);
|
||||
}
|
||||
|
||||
strategy.show();
|
||||
}
|
||||
}
|
||||
|
||||
// method to spawn a new wave of aliens
|
||||
public void newWave() {
|
||||
// deleting any existing bullets so the aliens don't spawn on top of them
|
||||
bullets.clear();
|
||||
|
||||
// speeding up the aliens
|
||||
Alien.speedUp();
|
||||
|
||||
// initial x and y coordinates for the aliens
|
||||
int alienx = 200;
|
||||
int alieny = 25;
|
||||
int column = 0; // keeps track of which column the alien is in
|
||||
for (int i = 0; i < NUMALIENS; i++) {
|
||||
aliensArray[i] = new Alien(alienImage, altAlienImage);
|
||||
aliensArray[i].setPosition(alienx, alieny);
|
||||
|
||||
alienx += 60;
|
||||
column++;
|
||||
|
||||
// go onto a new line every 5 aliens
|
||||
if (column >= 6) {
|
||||
column = 0;
|
||||
alienx = 200;
|
||||
alieny += 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// application entry point
|
||||
public static void main(String[] args) {
|
||||
InvadersApplication ia = new InvadersApplication();
|
||||
}
|
||||
}
|
13
second/semester2/CT255/Assignments/Assigment-05/Player.java
Normal file
@ -0,0 +1,13 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Player extends Sprite2D {
|
||||
public Player(Image image) {
|
||||
super(image);
|
||||
}
|
||||
|
||||
// method to move the player by the supplied distance
|
||||
public void move(int distance) {
|
||||
x += distance; // x is inherited from the Sprite2D superclass
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class PlayerBullet extends Sprite2D {
|
||||
public PlayerBullet(Player player, Image image) {
|
||||
super(image);
|
||||
x = player.getX() + 54/2;
|
||||
y = player.getY();
|
||||
}
|
||||
|
||||
// method to move the bullet up each frame
|
||||
public void move() {
|
||||
y = y - 10;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Sprite2D {
|
||||
// member data
|
||||
protected int x,y;
|
||||
protected Image image;
|
||||
public boolean isAlive; // boolean to tell if the sprite is alive or not
|
||||
|
||||
public Sprite2D(Image image) {
|
||||
this.image = image;
|
||||
this.isAlive = true;
|
||||
}
|
||||
|
||||
// paint method
|
||||
public void paint(Graphics g) {
|
||||
// draw the image
|
||||
g.drawImage(image, x, y, null);
|
||||
}
|
||||
|
||||
// set the position of the object
|
||||
public void setPosition(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
// getter method for the sprite's x position
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
// getter method for the sprite's y position
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
// method to set isAlive to false
|
||||
public void kill() {
|
||||
isAlive = false;
|
||||
}
|
||||
}
|
BIN
second/semester2/CT255/Assignments/Assigment-05/alien_ship_1.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
second/semester2/CT255/Assignments/Assigment-05/alien_ship_2.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
second/semester2/CT255/Assignments/Assigment-05/bullet.png
Executable file
After Width: | Height: | Size: 1.2 KiB |
BIN
second/semester2/CT255/Assignments/Assigment-05/player_ship.png
Executable file
After Width: | Height: | Size: 3.7 KiB |
1
second/semester2/CT255/Assignments/Assigment-05/todo.md
Normal file
@ -0,0 +1 @@
|
||||
- Multiple games
|
@ -0,0 +1,88 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.*;
|
||||
|
||||
public class GameOfLife extends JFrame implements Runnable, MouseListener {
|
||||
private static final Dimension WindowSize = new Dimension(800, 800);
|
||||
private BufferStrategy strategy;
|
||||
private static boolean isGraphicsInitialised = false;
|
||||
private boolean gameState[][] = new boolean[40][40];
|
||||
|
||||
public GameOfLife() {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
setVisible(true);
|
||||
|
||||
createBufferStrategy(2);
|
||||
strategy = getBufferStrategy();
|
||||
|
||||
// create a new thread & start it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
|
||||
// adding mouse listener
|
||||
addMouseListener(this);
|
||||
|
||||
isGraphicsInitialised = true;
|
||||
}
|
||||
|
||||
// entry point of the application
|
||||
public static void main(String[] args) {
|
||||
GameOfLife game = new GameOfLife();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
// repainting
|
||||
try {
|
||||
this.repaint();
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// application's paint method
|
||||
public void paint(Graphics g) {
|
||||
// making sure that the graphics are initialised before painting
|
||||
if (isGraphicsInitialised) {
|
||||
g = strategy.getDrawGraphics();
|
||||
|
||||
// draw a white rectangle on the whole canvas
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, 800, 800);
|
||||
|
||||
// looping through the gameState array
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
|
||||
// drawing a black square if true
|
||||
if (gameState[i][j]) {
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(i * 20, j * 20, 20, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strategy.show();
|
||||
}
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) { }
|
||||
public void mouseReleased(MouseEvent e) { }
|
||||
public void mouseEntered(MouseEvent e) { }
|
||||
public void mouseExited(MouseEvent e) { }
|
||||
|
||||
// mouse click event
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// setting boolean corresponding to the square that was clicked to true
|
||||
gameState[(int) Math.floor(e.getX() / 20)][(int) Math.floor(e.getY() / 20)] = true;
|
||||
}
|
||||
}
|
171
second/semester2/CT255/Assignments/Assigment-07/GameOfLife.java
Normal file
@ -0,0 +1,171 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
public class GameOfLife extends JFrame implements Runnable, MouseListener {
|
||||
private static final Dimension WindowSize = new Dimension(800, 800);
|
||||
private BufferStrategy strategy;
|
||||
private static boolean isGraphicsInitialised = false;
|
||||
private boolean gameState[][][] = new boolean[40][40][2];
|
||||
private static boolean isPlaying = false;
|
||||
|
||||
public GameOfLife() {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
setVisible(true);
|
||||
|
||||
createBufferStrategy(2);
|
||||
strategy = getBufferStrategy();
|
||||
|
||||
// create a new thread & start it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
|
||||
// adding mouse listener
|
||||
addMouseListener(this);
|
||||
|
||||
isGraphicsInitialised = true;
|
||||
}
|
||||
|
||||
// entry point of the application
|
||||
public static void main(String[] args) {
|
||||
GameOfLife game = new GameOfLife();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
// repainting
|
||||
try {
|
||||
this.repaint();
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// application's paint method
|
||||
public void paint(Graphics g) {
|
||||
// making sure that the graphics are initialised before painting
|
||||
if (isGraphicsInitialised) {
|
||||
g = strategy.getDrawGraphics();
|
||||
|
||||
// draw a white rectangle on the whole canvas
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0, 0, WindowSize.width, WindowSize.height);
|
||||
|
||||
// looping through the gameState array
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
|
||||
// drawing a white square if true
|
||||
if (gameState[i][j][0]) {
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(i * 20, j * 20, 20, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlaying) {
|
||||
for (int x = 0; x < 40; x++) {
|
||||
for (int y = 0; y < 40; y++) {
|
||||
// count the live neighbours of cell [x][y][0]
|
||||
int numLiveNeighbours = 0;
|
||||
|
||||
for (int xx = -1 ; xx <= 1; xx++) {
|
||||
for (int yy = -1; yy <= 1; yy++) {
|
||||
if (xx != 0 || yy != 0) {
|
||||
// check cell [x+xx][y+yy][0]
|
||||
// if x+xx or y+yy is out of bounds, getting the inverse of it modulo 40
|
||||
int newX = (x+xx >= 0) ? (x+xx) % 40 : 40 + x+xx;
|
||||
int newY = (y+yy >= 0) ? (y+yy) % 40 : 40 + y+yy;
|
||||
|
||||
if (gameState[newX][newY][0]) {
|
||||
numLiveNeighbours++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// killing the cell if it is alive and has fewer than two live neighbours or greater than 3 live neighbours
|
||||
if (gameState[x][y][0] && (numLiveNeighbours < 2 || numLiveNeighbours > 3)) {
|
||||
gameState[x][y][1] = false;
|
||||
}
|
||||
// bringing the cell back to life it is dead and has exactly 3 live neighbours
|
||||
else if (!gameState[x][y][0] && numLiveNeighbours == 3) {
|
||||
gameState[x][y][1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// making the "front buffer" equal to the "back buffer"
|
||||
for (int x = 0; x < 40; x++) {
|
||||
for (int y = 0; y < 40; y++) {
|
||||
gameState[x][y][0] = gameState[x][y][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the game is not being played, drawing the buttons
|
||||
else {
|
||||
Font f = new Font("Times", Font.PLAIN, 12);
|
||||
g.setFont(f);
|
||||
FontMetrics fm = getFontMetrics(f);
|
||||
|
||||
// drawing the two buttons
|
||||
g.setColor(Color.GREEN);
|
||||
|
||||
g.fillRect(20, 20, 60, 20);
|
||||
g.fillRect(100, 20, 60, 20);
|
||||
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawString("Start", 35, 35);
|
||||
g.drawString("Random", 105, 35);
|
||||
}
|
||||
|
||||
strategy.show();
|
||||
}
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) { }
|
||||
public void mouseReleased(MouseEvent e) { }
|
||||
public void mouseEntered(MouseEvent e) { }
|
||||
public void mouseExited(MouseEvent e) { }
|
||||
|
||||
// mouse click event
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// if (!isPlaying) {
|
||||
// if start button was pressed, switching to the playing game state
|
||||
if ((e.getX() >= 20 && e.getX() <= 80) && (e.getY() >= 20 && e.getY() <= 40)) {
|
||||
isPlaying = true;
|
||||
}
|
||||
// else if the random button was pressed, calling the random method
|
||||
else if ((e.getX() >= 100 && e.getX() <= 160) && (e.getY() >= 20 && e.getY() <= 40)) {
|
||||
random();
|
||||
}
|
||||
// else, setting the clicked square to true (white)
|
||||
else {
|
||||
// setting boolean corresponding to the square that was clicked to true
|
||||
gameState[(int) Math.floor(e.getX() / 20)][(int) Math.floor(e.getY() / 20)][0] = true;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// method to generate a random starting state
|
||||
public void random() {
|
||||
// looping through the gameState array
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
// setting the square to alive with a probability of 1 in 10
|
||||
if (((int) (Math.random() * 10)) == 1) {
|
||||
gameState[i][j][0] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
256
second/semester2/CT255/Assignments/Assigment-08/GameOfLife.java
Normal file
@ -0,0 +1,256 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class GameOfLife extends JFrame implements Runnable, MouseListener, MouseMotionListener {
|
||||
private static String workingDirectory = System.getProperty("user.dir");
|
||||
private static final Dimension WindowSize = new Dimension(800, 800);
|
||||
private BufferStrategy strategy;
|
||||
private static boolean isGraphicsInitialised = false;
|
||||
private boolean gameState[][][] = new boolean[40][40][2];
|
||||
private static boolean isPlaying = false;
|
||||
|
||||
public GameOfLife() {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
setVisible(true);
|
||||
|
||||
createBufferStrategy(2);
|
||||
strategy = getBufferStrategy();
|
||||
|
||||
// create a new thread & start it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
|
||||
// adding mouse listener
|
||||
addMouseListener(this);
|
||||
addMouseMotionListener(this);
|
||||
|
||||
isGraphicsInitialised = true;
|
||||
}
|
||||
|
||||
// entry point of the application
|
||||
public static void main(String[] args) {
|
||||
GameOfLife game = new GameOfLife();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
// repainting
|
||||
try {
|
||||
this.repaint();
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// application's paint method
|
||||
public void paint(Graphics g) {
|
||||
// making sure that the graphics are initialised before painting
|
||||
if (isGraphicsInitialised) {
|
||||
g = strategy.getDrawGraphics();
|
||||
|
||||
// draw a white rectangle on the whole canvas
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0, 0, WindowSize.width, WindowSize.height);
|
||||
|
||||
// looping through the gameState array
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
|
||||
// drawing a white square if true
|
||||
if (gameState[i][j][0]) {
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(i * 20, j * 20, 20, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlaying) {
|
||||
for (int x = 0; x < 40; x++) {
|
||||
for (int y = 0; y < 40; y++) {
|
||||
// count the live neighbours of cell [x][y][0]
|
||||
int numLiveNeighbours = 0;
|
||||
|
||||
for (int xx = -1 ; xx <= 1; xx++) {
|
||||
for (int yy = -1; yy <= 1; yy++) {
|
||||
if (xx != 0 || yy != 0) {
|
||||
// check cell [x+xx][y+yy][0]
|
||||
// if x+xx or y+yy is out of bounds, getting the inverse of it modulo 40
|
||||
int newX = (x+xx >= 0) ? (x+xx) % 40 : 40 + x+xx;
|
||||
int newY = (y+yy >= 0) ? (y+yy) % 40 : 40 + y+yy;
|
||||
|
||||
if (gameState[newX][newY][0]) {
|
||||
numLiveNeighbours++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// killing the cell if it is alive and has fewer than two live neighbours or greater than 3 live neighbours
|
||||
if (gameState[x][y][0] && (numLiveNeighbours < 2 || numLiveNeighbours > 3)) {
|
||||
gameState[x][y][1] = false;
|
||||
}
|
||||
// bringing the cell back to life it is dead and has exactly 3 live neighbours
|
||||
else if (!gameState[x][y][0] && numLiveNeighbours == 3) {
|
||||
gameState[x][y][1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// making the "front buffer" equal to the "back buffer"
|
||||
for (int x = 0; x < 40; x++) {
|
||||
for (int y = 0; y < 40; y++) {
|
||||
gameState[x][y][0] = gameState[x][y][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the game is not being played, drawing the buttons
|
||||
else {
|
||||
Font f = new Font("Times", Font.PLAIN, 12);
|
||||
g.setFont(f);
|
||||
FontMetrics fm = getFontMetrics(f);
|
||||
|
||||
// drawing the two buttons
|
||||
g.setColor(Color.GREEN);
|
||||
|
||||
g.fillRect( 20, 20, 60, 20);
|
||||
g.fillRect(100, 20, 60, 20);
|
||||
g.fillRect(180, 20, 60, 20);
|
||||
g.fillRect(260, 20, 60, 20);
|
||||
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawString("Start", 35, 35);
|
||||
g.drawString("Random", 105, 35);
|
||||
g.drawString("Save", 185, 35);
|
||||
g.drawString("Load", 265, 35);
|
||||
}
|
||||
|
||||
strategy.show();
|
||||
}
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) { }
|
||||
public void mouseReleased(MouseEvent e) { }
|
||||
public void mouseEntered(MouseEvent e) { }
|
||||
public void mouseExited(MouseEvent e) { }
|
||||
public void mouseMoved(MouseEvent e) { }
|
||||
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
// checking that index is in bounds before drawing
|
||||
if (e.getX() < 800 && e.getX() >= 0 && e.getY() < 800 && e.getY() >= 0) {
|
||||
gameState[(int) Math.floor(e.getX() / 20)][(int) Math.floor(e.getY() / 20)][0] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// mouse click event
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// if (!isPlaying) {
|
||||
// if start button was pressed, switching to the playing game state
|
||||
if ((e.getX() >= 20 && e.getX() <= 80) && (e.getY() >= 20 && e.getY() <= 40)) {
|
||||
isPlaying = true;
|
||||
}
|
||||
// else if the random button was pressed, calling the random method
|
||||
else if ((e.getX() >= 100 && e.getX() <= 160) && (e.getY() >= 20 && e.getY() <= 40)) {
|
||||
random();
|
||||
}
|
||||
// else if the save button was clicked
|
||||
else if ((e.getX() >= 180 && e.getX() <= 240) && (e.getY() >= 20 && e.getY() <= 40)) {
|
||||
save();
|
||||
}
|
||||
// else if the load button was clicked
|
||||
else if ((e.getX() >= 260 && e.getX() <= 320) && (e.getY() >= 20 && e.getY() <= 40)) {
|
||||
load();
|
||||
}
|
||||
// else, setting the clicked square to true (white)
|
||||
else {
|
||||
// setting boolean corresponding to the square that was clicked to true
|
||||
gameState[(int) Math.floor(e.getX() / 20)][(int) Math.floor(e.getY() / 20)][0] = true;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// method to generate a random starting state
|
||||
public void random() {
|
||||
// looping through the gameState array
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
// setting the square to alive with a probability of 1 in 10
|
||||
if (((int) (Math.random() * 10)) == 1) {
|
||||
gameState[i][j][0] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// method to save the gamestate to a txt file
|
||||
public void save() {
|
||||
// string that will be written to the file
|
||||
StringBuilder output = new StringBuilder();
|
||||
|
||||
// looping through each index in the array
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
// appending a 1 if true, 0 if false
|
||||
if (gameState[i][j][0]) {
|
||||
output.append("1");
|
||||
}
|
||||
else {
|
||||
output.append("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// writing the string to the file
|
||||
String filename = workingDirectory + "/gamestate.txt";
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
|
||||
writer.write(output.toString());
|
||||
writer.close();
|
||||
}
|
||||
catch (IOException e) {}
|
||||
}
|
||||
|
||||
// method to load the gamestate from a txt file
|
||||
public void load() {
|
||||
String filename = workingDirectory + "/gamestate.txt";
|
||||
String loadedtext = "";
|
||||
String line = null;
|
||||
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(filename));
|
||||
do {
|
||||
try {
|
||||
line = reader.readLine();
|
||||
|
||||
// appending to loadedtext if not null
|
||||
if (line != null) {
|
||||
loadedtext += line;
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
} while (line != null);
|
||||
} catch (IOException e) {}
|
||||
|
||||
// looping through each element of the front buffer and assigning true or false if the next char is 1 or 0
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
// getting the character that corresponds to the index of the array
|
||||
if (loadedtext.charAt(40*i + j) == '1') {
|
||||
gameState[i][j][0] = true;
|
||||
}
|
||||
else {
|
||||
gameState[i][j][0] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000001100000000000000000000000000000000000011100000000000000000000000000000000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111000000000000000000000000000000000001000100000000000000000000000000000000001100010000000000000000000000000000011111110001000000000000000000000000000011000000101100000000000000000000000000011000000011000000000000000000000000000001000000001110000000000000000000000000000100000001101000000000000000000000000000001110001100100000000000000000000000000000001111100110000000000000000000000000000000000011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
273
second/semester2/CT255/Assignments/Assigment-09/AStarMaze.java
Normal file
@ -0,0 +1,273 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
|
||||
public class AStarMaze extends JFrame implements Runnable, MouseListener, MouseMotionListener, KeyListener {
|
||||
|
||||
// member data
|
||||
private static final Dimension WindowSize = new Dimension(800, 800);
|
||||
private boolean isInitialised = false;
|
||||
private BufferStrategy strategy;
|
||||
private Graphics offscreenBuffer;
|
||||
private static boolean map[][] = new boolean[40][40];
|
||||
private boolean isGameRunning = false;
|
||||
private BadGuy badguy;
|
||||
private Player player;
|
||||
|
||||
private String FilePath;
|
||||
|
||||
// constructor
|
||||
public AStarMaze() {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
//Display the window, centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
setVisible(true);
|
||||
this.setTitle("A* Pathfinding Demo");
|
||||
|
||||
FilePath = System.getProperty("user.dir") + "/";
|
||||
|
||||
// load raster graphics and instantiate game objects
|
||||
ImageIcon icon = new ImageIcon(FilePath+"badguy.png");
|
||||
Image img = icon.getImage();
|
||||
badguy = new BadGuy(img);
|
||||
icon = new ImageIcon(FilePath+"player.png");
|
||||
img = icon.getImage();
|
||||
player = new Player(img);
|
||||
|
||||
// initialise double-buffering
|
||||
createBufferStrategy(2);
|
||||
strategy = getBufferStrategy();
|
||||
|
||||
// create and start our animation thread
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
|
||||
// register the Jframe itself to receive mouse and keyboard events
|
||||
addMouseListener(this);
|
||||
addMouseMotionListener(this);
|
||||
addKeyListener(this);
|
||||
|
||||
// initialise the map state
|
||||
for (x=0;x<40;x++) {
|
||||
for (y=0;y<40;y++) {
|
||||
map[x][y]=false;
|
||||
}
|
||||
}
|
||||
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
// thread's entry point
|
||||
public void run() {
|
||||
long loops = 0;
|
||||
|
||||
while (true) {
|
||||
// 1: sleep for 1/5 sec
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) { }
|
||||
|
||||
// 2: animate game objects
|
||||
if (isGameRunning) {
|
||||
loops++;
|
||||
player.move(map); // player moves every frame
|
||||
|
||||
// recalculating the badguys path every move, highly inefficient but easier to program lol
|
||||
badguy.reCalcPath(map, player.x, player.y);
|
||||
|
||||
if (loops%10==0) // badguy moves once every 3 frames
|
||||
badguy.move(map,player.x,player.y);
|
||||
}
|
||||
|
||||
// 3: force an application repaint
|
||||
this.repaint();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMaze() {
|
||||
String filename = FilePath+"maze.txt";
|
||||
String textinput = null;
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(filename));
|
||||
textinput = reader.readLine();
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e) { }
|
||||
|
||||
if (textinput!=null) {
|
||||
for (int x=0;x<40;x++) {
|
||||
for (int y=0;y<40;y++) {
|
||||
map[x][y] = (textinput.charAt(x*40+y)=='1');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveMaze() {
|
||||
// pack maze into a string
|
||||
String outputtext="";
|
||||
for (int x=0;x<40;x++) {
|
||||
for (int y=0;y<40;y++) {
|
||||
if (map[x][y])
|
||||
outputtext+="1";
|
||||
else
|
||||
outputtext+="0";
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
String filename = FilePath+"maze.txt";
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
|
||||
writer.write(outputtext);
|
||||
writer.close();
|
||||
}
|
||||
catch (IOException e) { }
|
||||
}
|
||||
|
||||
// mouse events which must be implemented for MouseListener
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (!isGameRunning) {
|
||||
// was the click on the 'start button'?
|
||||
int x = e.getX();
|
||||
int y = e.getY();
|
||||
if (x>=15 && x<=85 && y>=40 && y<=70) {
|
||||
isGameRunning=true;
|
||||
return;
|
||||
}
|
||||
// or the 'load' button?
|
||||
if (x>=315 && x<=385 && y>=40 && y<=70) {
|
||||
loadMaze();
|
||||
return;
|
||||
}
|
||||
// or the 'save' button?
|
||||
if (x>=415 && x<=485 && y>=40 && y<=70) {
|
||||
saveMaze();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// determine which cell of the gameState array was clicked on
|
||||
int x = e.getX()/20;
|
||||
int y = e.getY()/20;
|
||||
// toggle the state of the cell
|
||||
map[x][y] = !map[x][y];
|
||||
// throw an extra repaint, to get immediate visual feedback
|
||||
this.repaint();
|
||||
// store mouse position so that each tiny drag doesn't toggle the cell
|
||||
// (see mouseDragged method below)
|
||||
prevx=x;
|
||||
prevy=y;
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e) {}
|
||||
|
||||
public void mouseEntered(MouseEvent e) {}
|
||||
|
||||
public void mouseExited(MouseEvent e) {}
|
||||
|
||||
public void mouseClicked(MouseEvent e) {}
|
||||
//
|
||||
|
||||
// mouse events which must be implemented for MouseMotionListener
|
||||
public void mouseMoved(MouseEvent e) {}
|
||||
|
||||
// mouse position on previous mouseDragged event
|
||||
// must be member variables for lifetime reasons
|
||||
int prevx=-1, prevy=-1;
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
// determine which cell of the gameState array was clicked on
|
||||
// and make sure it has changed since the last mouseDragged event
|
||||
if (e.getX() < 800 && e.getX() >= 0 && e.getY() < 800 && e.getY() >= 0) {
|
||||
int x = e.getX()/20;
|
||||
int y = e.getY()/20;
|
||||
if (x!=prevx || y!=prevy) {
|
||||
// toggle the state of the cell
|
||||
map[x][y] = !map[x][y];
|
||||
// throw an extra repaint, to get immediate visual feedback
|
||||
this.repaint();
|
||||
// store mouse position so that each tiny drag doesn't toggle the cell
|
||||
prevx=x;
|
||||
prevy=y;
|
||||
}
|
||||
}
|
||||
badguy.reCalcPath(map, player.x, player.y);
|
||||
}
|
||||
|
||||
// Keyboard events
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode()==KeyEvent.VK_LEFT)
|
||||
player.setXSpeed(-1);
|
||||
else if (e.getKeyCode()==KeyEvent.VK_RIGHT)
|
||||
player.setXSpeed(1);
|
||||
else if (e.getKeyCode()==KeyEvent.VK_UP)
|
||||
player.setYSpeed(-1);
|
||||
else if (e.getKeyCode()==KeyEvent.VK_DOWN)
|
||||
player.setYSpeed(1);
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode()==KeyEvent.VK_LEFT || e.getKeyCode()==KeyEvent.VK_RIGHT)
|
||||
player.setXSpeed(0);
|
||||
else if (e.getKeyCode()==KeyEvent.VK_UP || e.getKeyCode()==KeyEvent.VK_DOWN)
|
||||
player.setYSpeed(0);
|
||||
}
|
||||
|
||||
public void keyTyped(KeyEvent e) { }
|
||||
|
||||
// application's paint method
|
||||
public void paint(Graphics g) {
|
||||
if (!isInitialised)
|
||||
return;
|
||||
|
||||
// g = offscreenBuffer; // draw to offscreen buffer
|
||||
g = strategy.getDrawGraphics();
|
||||
|
||||
// clear the canvas with a big black rectangle
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0, 0, 800, 800);
|
||||
|
||||
// redraw the map
|
||||
g.setColor(Color.WHITE);
|
||||
for (int x=0;x<40;x++) {
|
||||
for (int y=0;y<40;y++) {
|
||||
if (map[x][y]) {
|
||||
g.fillRect(x*20, y*20, 20, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
// redraw the player and badguy
|
||||
// paint the game objects
|
||||
player.paint(g);
|
||||
badguy.paint(g);
|
||||
|
||||
if (!isGameRunning) {
|
||||
// game is not running..
|
||||
// draw a 'start button' as a rectangle with text on top
|
||||
// also draw 'load' and 'save' buttons
|
||||
g.setColor(Color.GREEN);
|
||||
g.fillRect(15, 40, 70, 30);
|
||||
g.fillRect(315, 40, 70, 30);
|
||||
g.fillRect(415, 40, 70, 30);
|
||||
g.setFont(new Font("Times", Font.PLAIN, 24));
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawString("Start", 22, 62);
|
||||
g.drawString("Load", 322, 62);
|
||||
g.drawString("Save", 422, 62);
|
||||
}
|
||||
|
||||
// flip the buffers
|
||||
strategy.show();
|
||||
}
|
||||
|
||||
// application entry point
|
||||
public static void main(String[] args) {
|
||||
AStarMaze w = new AStarMaze();
|
||||
}
|
||||
|
||||
}
|
298
second/semester2/CT255/Assignments/Assigment-09/BadGuy.java
Normal file
@ -0,0 +1,298 @@
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
public class BadGuy {
|
||||
/* list of nodes to which the algorithm has already found a route (i.e., one of its conencted neighbours has been expanded)
|
||||
* but have not themselves been expanded */
|
||||
LinkedList<Node> openlist = new LinkedList<Node>();
|
||||
|
||||
// list of nodes that have been expanded and which therefore should not be revisited
|
||||
LinkedList<Node> closedlist = new LinkedList<Node>();
|
||||
|
||||
Node[][] allnodes = new Node[40][40] ; // array of all the nodes
|
||||
|
||||
Stack<Node> finalpath = new Stack<Node>();
|
||||
|
||||
Image myImage;
|
||||
int x=0,y=0;
|
||||
boolean hasPath=false;
|
||||
|
||||
public BadGuy( Image i ) {
|
||||
myImage=i;
|
||||
x = 30;
|
||||
y = 10;
|
||||
}
|
||||
|
||||
public void reCalcPath(boolean map[][],int targx, int targy) {
|
||||
System.out.println();
|
||||
System.out.println("recalculating path");
|
||||
hasPath = false;
|
||||
openlist.clear();
|
||||
closedlist.clear();
|
||||
finalpath.clear();
|
||||
|
||||
// looping through map[][], generating each node, and marking each wall node as closed
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int j = 0; j < 40; j++) {
|
||||
allnodes[i][j] = new Node(i, j); // generating node
|
||||
|
||||
if (map[i][j]) {
|
||||
allnodes[i][j].closed = true;
|
||||
allnodes[i][j].open = false;
|
||||
|
||||
closedlist.add(allnodes[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate f,g,h for the starting node and set to open
|
||||
Node starting = allnodes[x][y];
|
||||
starting.g = 0;
|
||||
starting.h = targx - x + targy - y; // manhattan distance
|
||||
starting.f = starting.g + starting.h;
|
||||
starting.open = true;
|
||||
starting.closed = false;
|
||||
openlist.add(starting);
|
||||
|
||||
|
||||
// looping while a path has not been found
|
||||
// end condition: if a neighbour is the target, or if there are no open nodes
|
||||
while (!hasPath) {
|
||||
// breaking if there are no open nodes
|
||||
if (openlist.size() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* progress is made by identifying the most promising node in the open list (i.e., the one with lowest f value) and
|
||||
* expanding it by adding each of its connected neighbours to the open list, unless they are already closed. */
|
||||
|
||||
// looping through open list to find most promising node
|
||||
Node mostpromising = openlist.get(0);
|
||||
for (int i = 1; i < openlist.size(); i++) {
|
||||
if (openlist.get(i).f < mostpromising.f) {
|
||||
mostpromising = openlist.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
int mx = mostpromising.x;
|
||||
int my = mostpromising.y;
|
||||
|
||||
// expanding the most promising node by adding each of its connected neighbours to the open list, unless they are already closed
|
||||
// as nodes are added to the open list, their f, g, h, & parent values are recorded
|
||||
// the g value of a node is equal to the g value of its parent + the cost of moving from the parent to the node itself. t
|
||||
|
||||
// as nodes are expanded, they are moved to the closed list
|
||||
mostpromising.open = false;
|
||||
mostpromising.closed = true;
|
||||
closedlist.add(mostpromising);
|
||||
// openlist.remove(mostpromising);
|
||||
|
||||
// northwest neighbour
|
||||
if (mx-1 >= 0 && my-1 >= 0 && !allnodes[mx-1][my-1].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx-1 == targx && my-1 == targy) {
|
||||
allnodes[mx-1][my-1].open = true;
|
||||
allnodes[mx-1][my-1].closed = false;
|
||||
closedlist.remove(allnodes[mx-1][my-1]);
|
||||
openlist.add(allnodes[mx-1][my-1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx-1][my-1].open) {
|
||||
allnodes[mx-1][my-1].g = mostpromising.g + 1;
|
||||
allnodes[mx-1][my-1].h = targx - mx + targy - my;
|
||||
allnodes[mx-1][my-1].f = allnodes[mx-1][my-1].g + allnodes[mx-1][my-1].h;
|
||||
allnodes[mx-1][my-1].open = true;
|
||||
allnodes[mx-1][my-1].closed = false;
|
||||
openlist.add(allnodes[mx-1][my-1]);
|
||||
}
|
||||
}
|
||||
|
||||
// north neighbour
|
||||
if (my-1 >= 0 && !allnodes[mx][my-1].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx == targx && my-1 == targy) {
|
||||
allnodes[mx][my-1].open = true;
|
||||
allnodes[mx][my-1].closed = false;
|
||||
closedlist.remove(allnodes[mx][my-1]);
|
||||
openlist.add(allnodes[mx][my-1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx][my-1].open) {
|
||||
allnodes[mx][my-1].g = mostpromising.g + 1;
|
||||
allnodes[mx][my-1].h = targx - mx + targy - my;
|
||||
allnodes[mx][my-1].f = allnodes[mx][my-1].g + allnodes[mx][my-1].h;
|
||||
allnodes[mx][my-1].open = true;
|
||||
allnodes[mx][my-1].closed = false;
|
||||
openlist.add(allnodes[mx][my-1]);
|
||||
}
|
||||
}
|
||||
|
||||
// northeast neighbour
|
||||
if (mx+1 < 40 && my-1 >= 0 && !allnodes[mx+1][my-1].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx+1 == targx && my-1 == targy) {
|
||||
allnodes[mx+1][my-1].open = true;
|
||||
allnodes[mx+1][my-1].closed = false;
|
||||
closedlist.remove(allnodes[mx+1][my-1]);
|
||||
openlist.add(allnodes[mx+1][my-1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx+1][my-1].open && !allnodes[mx+1][my-1].closed) {
|
||||
allnodes[mx+1][my-1].g = mostpromising.g + 1;
|
||||
allnodes[mx+1][my-1].h = targx - mx+1 + targy - my;
|
||||
allnodes[mx+1][my-1].f = allnodes[mx+1][my-1].g + allnodes[mx+1][my-1].h;
|
||||
allnodes[mx+1][my-1].open = true;
|
||||
allnodes[mx+1][my-1].closed = false;
|
||||
openlist.add(allnodes[mx+1][my-1]);
|
||||
}
|
||||
}
|
||||
|
||||
// west neighbour
|
||||
if (mx-1 >= 0 && !allnodes[mx-1][my].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx-1 == targx && my == targy) {
|
||||
allnodes[mx-1][my].open = true;
|
||||
allnodes[mx-1][my].closed = false;
|
||||
closedlist.remove(allnodes[mx-1][my]);
|
||||
openlist.add(allnodes[mx-1][my]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx-1][my].open && !allnodes[mx-1][my].closed) {
|
||||
allnodes[mx-1][my].g = mostpromising.g + 1;
|
||||
allnodes[mx-1][my].h = targx - mx + targy - my;
|
||||
allnodes[mx-1][my].f = allnodes[mx-1][my].g + allnodes[mx-1][my].h;
|
||||
allnodes[mx-1][my].open = true;
|
||||
allnodes[mx-1][my].closed = false;
|
||||
openlist.add(allnodes[mx-1][my]);
|
||||
}
|
||||
}
|
||||
|
||||
// east neighbour
|
||||
if (mx+1 < 40 && !allnodes[mx+1][my].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx+1 == targx && my == targy) {
|
||||
allnodes[mx+1][my].open = true;
|
||||
allnodes[mx+1][my].closed = false;
|
||||
closedlist.remove(allnodes[mx+1][my]);
|
||||
openlist.add(allnodes[mx+1][my]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx+1][my].open) {
|
||||
allnodes[mx+1][my].g = mostpromising.g + 1;
|
||||
allnodes[mx+1][my].h = targx - mx+1 + targy - my;
|
||||
allnodes[mx+1][my].f = allnodes[mx+1][my].g + allnodes[mx+1][my].h;
|
||||
allnodes[mx+1][my].open = true;
|
||||
allnodes[mx+1][my].closed = false;
|
||||
openlist.add(allnodes[mx+1][my]);
|
||||
}
|
||||
}
|
||||
|
||||
// southwest neighbour
|
||||
if (mx-1 >= 0 && my+1 < 40 && !allnodes[mx-1][my+1].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx-1 == targx && my+1 == targy) {
|
||||
allnodes[mx-1][my+1].open = true;
|
||||
allnodes[mx-1][my+1].closed = false;
|
||||
closedlist.remove(allnodes[mx-1][my+1]);
|
||||
openlist.add(allnodes[mx-1][my+1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx-1][my+1].open) {
|
||||
allnodes[mx-1][my+1].g = mostpromising.g + 1;
|
||||
allnodes[mx-1][my+1].h = targx - mx + targy - my;
|
||||
allnodes[mx-1][my+1].f = allnodes[mx-1][my+1].g + allnodes[mx-1][my+1].h;
|
||||
allnodes[mx-1][my+1].open = true;
|
||||
allnodes[mx-1][my+1].closed = false;
|
||||
openlist.add(allnodes[mx-1][my+1]);
|
||||
}
|
||||
}
|
||||
|
||||
// south neighbour
|
||||
if (my+1 < 40 && !allnodes[mx][my+1].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx == targx && my+1 == targy) {
|
||||
allnodes[mx][my+1].open = true;
|
||||
allnodes[mx][my+1].closed = false;
|
||||
closedlist.remove(allnodes[mx][my+1]);
|
||||
openlist.add(allnodes[mx][my+1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx][my+1].open) {
|
||||
allnodes[mx][my+1].g = mostpromising.g + 1;
|
||||
allnodes[mx][my+1].h = targx - mx + targy - my;
|
||||
allnodes[mx][my+1].f = allnodes[mx][my+1].g + allnodes[mx][my+1].h;
|
||||
allnodes[mx][my+1].open = true;
|
||||
allnodes[mx][my+1].closed = false;
|
||||
openlist.add(allnodes[mx][my+1]);
|
||||
}
|
||||
}
|
||||
|
||||
// southeast neighbour
|
||||
if (mx+1 < 40 && my+1 < 40 && !allnodes[mx+1][my+1].closed) {
|
||||
// checking if this node is the target node, and breaking if so
|
||||
if (mx+1 == targx && my+1 == targy) {
|
||||
allnodes[mx+1][my+1].open = true;
|
||||
allnodes[mx+1][my+1].closed = false;
|
||||
closedlist.remove(allnodes[mx+1][my+1]);
|
||||
openlist.add(allnodes[mx+1][my+1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!allnodes[mx+1][my+1].open) {
|
||||
allnodes[mx+1][my+1].g = mostpromising.g + 1;
|
||||
allnodes[mx+1][my+1].h = targx - mx+1 + targy - my;
|
||||
allnodes[mx+1][my+1].f = allnodes[mx+1][my+1].g + allnodes[mx+1][my+1].h;
|
||||
allnodes[mx+1][my+1].open = true;
|
||||
allnodes[mx+1][my+1].closed = false;
|
||||
openlist.add(allnodes[mx+1][my+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generate final path by pushing target onto stack, followed by its parent in closedlist, ..., followed by start node
|
||||
|
||||
for (int i = openlist.size()-1; i >= 0; i--) {
|
||||
System.out.println("pushing x=" + openlist.get(i).x + " y =" + openlist.get(i).y);
|
||||
finalpath.push(openlist.get(i));
|
||||
}
|
||||
|
||||
hasPath = true;
|
||||
return;
|
||||
}
|
||||
|
||||
public void move(boolean map[][],int targx, int targy) {
|
||||
if (hasPath) {
|
||||
Node nextnode = finalpath.pop();
|
||||
System.out.println("next node x=" + nextnode.x + " y=" + nextnode.y);
|
||||
x = nextnode.x;
|
||||
y = nextnode.y;
|
||||
}
|
||||
else {
|
||||
// no path known, so just do a dumb 'run towards' behaviour
|
||||
int newx=x, newy=y;
|
||||
if (targx<x)
|
||||
newx--;
|
||||
else if (targx>x)
|
||||
newx++;
|
||||
if (targy<y)
|
||||
newy--;
|
||||
else if (targy>y)
|
||||
newy++;
|
||||
if ((newx < 40 && newx >= 0 && newy < 40 && newy >=0) && !map[newx][newy]) {
|
||||
x=newx;
|
||||
y=newy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
g.drawImage(myImage, x*20, y*20, null);
|
||||
}
|
||||
}
|
15
second/semester2/CT255/Assignments/Assigment-09/Node.java
Normal file
@ -0,0 +1,15 @@
|
||||
public class Node {
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
public int g; // cost of getting from the starting node to this node
|
||||
public int h; // estimated heuristic cost of getting from this node to the target node
|
||||
public int f; // sum of g & h, the algorithm's best current estimate as to the total cost of travelling from the starting location to the target location via this node
|
||||
public boolean closed = false;
|
||||
public boolean open = false;
|
||||
|
||||
public Node(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
42
second/semester2/CT255/Assignments/Assigment-09/Player.java
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
|
||||
|
||||
public class Player {
|
||||
|
||||
Image myImage;
|
||||
int x=0,y=0;
|
||||
int xSpeed=0, ySpeed=0;
|
||||
|
||||
public Player( Image i ) {
|
||||
myImage=i;
|
||||
x=10;
|
||||
y=35;
|
||||
}
|
||||
|
||||
public void setXSpeed( int x ) {
|
||||
xSpeed=x;
|
||||
}
|
||||
|
||||
public void setYSpeed( int y ) {
|
||||
ySpeed=y;
|
||||
}
|
||||
|
||||
public void move(boolean map[][]) {
|
||||
int newx=x+xSpeed;
|
||||
int newy=y+ySpeed;
|
||||
|
||||
// making sure that the newx & newy are not off the map or blocked
|
||||
// if (e.getX() < 800 && e.getX() >= 0 && e.getY() < 800 && e.getY() >= 0) {
|
||||
if ((newx < 40 && newx >= 0 && newy < 40 && newy >=0) && !map[newx][newy]) {
|
||||
x=newx;
|
||||
y=newy;
|
||||
}
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
g.drawImage(myImage, x*20, y*20, null);
|
||||
}
|
||||
|
||||
}
|
BIN
second/semester2/CT255/Assignments/Assigment-09/badguy.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
1
second/semester2/CT255/Assignments/Assigment-09/maze.txt
Normal file
@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000001100000000000000000000000000000000000000110000000000000000000000000000000000000001000000000000000000000000000000000000000100000000000000000000000000000000000000010000000000000000000000000000000000000011000000000000000000000011111111111111111100000000000000000000000000000000000000110000000000000000000000000000000000000001000000000000000000000000000000000000000100000000000000000000000000000000000000010000000000000000000000000000000000000011000000000000000000000000000000000000001100000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
BIN
second/semester2/CT255/Assignments/Assigment-09/player.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
110
second/semester2/CT255/Assignments/Assigment-10/Cave.java
Normal file
@ -0,0 +1,110 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class Cave extends JFrame implements Runnable {
|
||||
private static final Dimension WindowSize = new Dimension(800, 800);
|
||||
private static boolean isGraphicsInitialised = false;
|
||||
private boolean map[][][] = new boolean[200][200][2];
|
||||
|
||||
public Cave() {
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
// randomly deciding whether each position in the map is a wall (true) or floor (false)
|
||||
for (int i = 0; i < 200; i++) {
|
||||
for (int j = 0; j < 200; j++) {
|
||||
// setting the square to wall with a probability of 60%
|
||||
map[i][j][0] = Math.random() < 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
// display the window. centred on the screen
|
||||
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = screensize.width/2 - WindowSize.width/2; int y = screensize.height/2 - WindowSize.height/2;
|
||||
setBounds(x, y, WindowSize.width, WindowSize.height);
|
||||
setVisible(true);
|
||||
|
||||
// create a new thread & start it
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
|
||||
isGraphicsInitialised = true;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if (isGraphicsInitialised) {
|
||||
// looping 5 times to show the initial state also, but re-running the cave procedure 4 times
|
||||
for (int i = 0; i <= 4; i++){
|
||||
// repainting
|
||||
try {
|
||||
this.repaint();
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paint (Graphics g) {
|
||||
// draw a white rectangle on the whole canvas
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0, 0, WindowSize.width, WindowSize.height);
|
||||
|
||||
// looping through map and drawing a white square if floor (true)
|
||||
for (int i = 0; i < 200; i++) {
|
||||
for (int j = 0; j < 200; j++) {
|
||||
// drawing a white square if true
|
||||
if (map[i][j][0]) {
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(i * 4, j * 4, 4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// looping through array to make clumping happen
|
||||
for (int x = 0; x < 200; x++) {
|
||||
for (int y = 0; y < 200; y++) {
|
||||
// count the wall neighbours of cell [x][y]
|
||||
int numWallNeighbours = 0;
|
||||
|
||||
// looping through neighbour cells
|
||||
for (int xx = -1 ; xx <= 1; xx++) {
|
||||
for (int yy = -1; yy <= 1; yy++) {
|
||||
if (xx != 0 || yy != 0) {
|
||||
// check cell [x+xx][y+yy]()
|
||||
// if x+xx or y+yy is out of bounds, getting the inverse of it modulo 200
|
||||
int newX = (x+xx >= 0) ? (x+xx) % 200 : 200 + x+xx;
|
||||
int newY = (y+yy >= 0) ? (y+yy) % 200 : 200 + y+yy;
|
||||
|
||||
// if the neighbour is a wall, increasing the count
|
||||
if (map[newX][newY][0]) {
|
||||
numWallNeighbours++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// defining each cell that has at least 5 neighbouring wall cells as a wall itself
|
||||
if (numWallNeighbours >= 5) {
|
||||
map[x][y][1] = true;
|
||||
}
|
||||
// otherwise defining it as a floor
|
||||
else {
|
||||
map[x][y][1] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// moving back buffer to front
|
||||
for (int x = 0; x < 200; x++) {
|
||||
for (int y = 0; y < 200; y++) {
|
||||
map[x][y][0] = map[x][y][1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Cave cave = new Cave();
|
||||
}
|
||||
}
|
BIN
second/semester2/CT255/Notes/CT255-Notes.pdf
Normal file
552
second/semester2/CT255/Notes/CT255-Notes.tex
Normal file
@ -0,0 +1,552 @@
|
||||
\documentclass[11pt]{article}
|
||||
|
||||
\usepackage{report}
|
||||
|
||||
\usepackage[utf8]{inputenc} % allow utf-8 input
|
||||
\usepackage[T1]{fontenc} % use 8-bit T1 fonts
|
||||
\usepackage[colorlinks=true, linkcolor=black, citecolor=blue, urlcolor=blue]{hyperref} % hyperlinks
|
||||
\usepackage{url} % simple URL typesetting
|
||||
\usepackage{booktabs} % professional-quality tables
|
||||
\usepackage{amsfonts} % blackboard math symbols
|
||||
\usepackage{nicefrac} % compact symbols for 1/2, etc.
|
||||
\usepackage{microtype} % microtypography
|
||||
\usepackage{lipsum} % Can be removed after putting your text content
|
||||
\usepackage{graphicx}
|
||||
\graphicspath{ {./images/} }
|
||||
\usepackage{natbib}
|
||||
\usepackage{doi}
|
||||
\setcitestyle{aysep={,}}
|
||||
\usepackage{array}
|
||||
|
||||
\usepackage{listings}
|
||||
\usepackage{xcolor}
|
||||
\definecolor{codegreen}{rgb}{0,0.6,0}
|
||||
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
|
||||
\definecolor{codeorange}{rgb}{1,0.49,0}
|
||||
\definecolor{backcolour}{rgb}{0.95,0.95,0.96}
|
||||
|
||||
\lstdefinestyle{mystyle}{
|
||||
backgroundcolor=\color{backcolour},
|
||||
commentstyle=\color{codegray},
|
||||
keywordstyle=\color{codeorange},
|
||||
numberstyle=\tiny\color{codegray},
|
||||
stringstyle=\color{codegreen},
|
||||
basicstyle=\ttfamily\footnotesize,
|
||||
breakatwhitespace=false,
|
||||
breaklines=true,
|
||||
captionpos=b,
|
||||
keepspaces=true,
|
||||
numbers=left,
|
||||
numbersep=5pt,
|
||||
showspaces=false,
|
||||
showstringspaces=false,
|
||||
showtabs=false,
|
||||
tabsize=2,
|
||||
xleftmargin=10pt,
|
||||
}
|
||||
|
||||
\lstset{style=mystyle}
|
||||
|
||||
\title{CT255 - Next Gen Technologies II}
|
||||
|
||||
\author{Andrew Hayes\\
|
||||
\AND
|
||||
Student ID: 21321503\\
|
||||
\AND
|
||||
\AND
|
||||
\AND
|
||||
\AND
|
||||
2BCT\\
|
||||
\AND
|
||||
University of Galway\\
|
||||
}
|
||||
|
||||
% Uncomment to remove the date
|
||||
\date{February 2022}
|
||||
|
||||
% Uncomment to override the `A preprint' in the header
|
||||
\renewcommand{\headeright}{2D Games Programming in Java}
|
||||
\renewcommand{\undertitle}{2D Games Programming in Java}
|
||||
\renewcommand{\shorttitle}{}
|
||||
|
||||
%%% Add PDF metadata to help others organize their library
|
||||
%%% Once the PDF is generated, you can check the metadata with
|
||||
%%% $ pdfinfo template.pdf
|
||||
% \hypersetup{
|
||||
% pdftitle={A template for the arxiv style},
|
||||
% pdfsubject={q-bio.NC, q-bio.QM},
|
||||
% pdfauthor={David S.~Hippocampus, Elias D.~Striatum},
|
||||
% pdfkeywords={First keyword, Second keyword, More},
|
||||
% }
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\newpage
|
||||
\tableofcontents
|
||||
\thispagestyle{empty}
|
||||
|
||||
|
||||
\newpage
|
||||
\setcounter{page}{1}
|
||||
\section{Lecture 1}
|
||||
\subsection{2D Co-Ordinate System}
|
||||
The \textbf{JFrame} class will provide a Window with associated graphics canvas \& a pixel-based
|
||||
co-ordinate system with the origin at (0,0) on the top \textbf(left).
|
||||
A JFrame is a top-level window with a title \& a border.
|
||||
To have access to JFrame and associated methods:
|
||||
\\
|
||||
\verb|import java.awt.*;| \\
|
||||
\verb|import javax.swing.*;|
|
||||
|
||||
|
||||
The top 50 pixels or so are hidden by the window's title bar (depending on the operating system).
|
||||
|
||||
\subsection{Basic Graphics in Java}
|
||||
2D graphics can be drawn using the \verb|Graphics| class.
|
||||
This provides methods for drawing ``primitives'' (lines, circles, boxes) and also images (.jpg, .png, etc.).
|
||||
|
||||
The \verb|paint()| method of the \verb|JFrame| class is automatically invoked whenever it needs to be
|
||||
painted (system-invoked).
|
||||
Otherwise, you can force painting to happen via \verb|repaint()| if you need to repaint when the OS
|
||||
doesn't think that it's needed.
|
||||
|
||||
\begin{lstlisting}[language=Java]
|
||||
public void paint (Graphics g) {
|
||||
// use the "g" object to draw graphics
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Drawing Text using Methods of the Graphics Class}
|
||||
\begin{lstlisting}[language=Java]
|
||||
public void paint (Graphics g) {
|
||||
Font f = new Font("Times", Font.PLAIN, 24);
|
||||
g.setFont(f);
|
||||
Color c = Color.BLACK;
|
||||
g.setColor(c);
|
||||
g.drawString("Pacman!", 20, 60);
|
||||
}
|
||||
\end{lstlisting}.
|
||||
|
||||
This should be added as a method of the application class.
|
||||
|
||||
\section{Lecture 2}
|
||||
\subsection{Animation with Threads}
|
||||
|
||||
\textbf{Animation} is the changing of grahics over time, e.g., moving a spaceship across the screen, changing its position by
|
||||
one pixel every 0.02 seconds.
|
||||
|
||||
One of the best ways to do periodic execution of code is to use \textbf{threads}.
|
||||
Threads allow multiple taks to run independently/concurrently within a program.
|
||||
Essentially, this means that we spawn a separate execution ``branch'' that operates independently of our program's main flow of control.
|
||||
For example, the new thread could repeatedly sleep for 20ms, then carry out an animation, and call \verb|this.repaint()| on the application.
|
||||
|
||||
\subsubsection{Implementing Threads in Java}
|
||||
Your application class should implement the \verb|Runnable| interface, i.e.:
|
||||
\begin{lstlisting}[language=Java]
|
||||
public class MyApplication extends JFrame implements Runnable {
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Your application now \textbf{must} provide an implementation for the \verb|run()| method, which is executed when a thread is started, serving as its ``main'' function, i.e.:
|
||||
\begin{lstlisting}[language=Java]
|
||||
public void run(){
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
To create \& start a new thread running from your application class:
|
||||
\begin{lstlisting}[language=Java]
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
\end{lstlisting}
|
||||
|
||||
The typical actions of an animation thread are as follows:
|
||||
\begin{enumerate}
|
||||
\item Sleep for (say) 20ms using \verb|Thread.sleep(20);|. Note that you will be \textbf{required} to handle \verb|InterruptedException|.
|
||||
\item Carry out movement of game objects.
|
||||
\item Call \verb|this.repaint();| which (indirectly) invokes our \verb|paint(Graphics g)| method.
|
||||
\item Go back to Step 1.
|
||||
\end{enumerate}
|
||||
|
||||
\subsubsection{Threads Test}
|
||||
\begin{lstlisting}[language=Java]
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class ThreadsTest implements Runnable {
|
||||
public ThreadsTest() {
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("Thread started");
|
||||
|
||||
for (int i = 0; i < 15; i++) {
|
||||
System.out.println("Loop " + i + "Start");
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("Loop " + i + " end");
|
||||
}
|
||||
System.out.println("Thread ended");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ThreadsTest tt = new ThreadsTest();
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Game Object Classes}
|
||||
Games typically have \textbf{game object classes} (spaceships, alines, cars, bullets, etc.).
|
||||
Numerous instances of each may exist at runtime.
|
||||
This class encapsulates the data (position, colour, etc.) and code (move, draw, die, etc.) associated with the game object.
|
||||
|
||||
Typically, we store these instances in a data structure such as an array, so that during our animation \& painting phases we can iterated through them all and invoke the \verb|animate()| \& \verb|paint()| methods on each instance.
|
||||
|
||||
\section{Lecture 03}
|
||||
\subsection{Handling Keyboard Input}
|
||||
In GUI-based languages such as Java (with AWT), the mouse \& keyboard are handled as ``\textbf{events}''.
|
||||
These events may happen at any time.
|
||||
Events are queued as they happen and are dealt with at the next free, idle time.
|
||||
AWT handles events coming from the OS by dispatching them to \textit{listeners} registered to those events.
|
||||
|
||||
To handle keyboard input:
|
||||
\begin{enumerate}
|
||||
\item Make a class that implements \verb|KeyListener|. Make sure that you have an instance of this class.
|
||||
\item Add this instance as a key listener attached to the \verb|JFrame| that receives the messages from the OS.
|
||||
The simplest way is to make your JFrame-derived class handle the events it receives itself.
|
||||
\end{enumerate}
|
||||
|
||||
\begin{lstlisting}[language=Java]
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class MyApplication extends JFrame implements KeyListener {
|
||||
public MyApplication() {
|
||||
// send keyboard events arriving into this JFrame to its own event handlers.
|
||||
addKeyListener(this);
|
||||
}
|
||||
|
||||
// 3 keyboard event handler functions
|
||||
public void keyPressed(KeyEvent e) {
|
||||
}
|
||||
public void keyReleased(Event e) {
|
||||
}
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Notes:
|
||||
\begin{itemize}
|
||||
\item The \verb|KeyEvent| parameter \verb|e| provides the ``virtual keycode'' of the key that has triggered the event, and constants are defined to match these values, e.g., \verb|KeyEvent.VK_Q| or \verb|KeyEvent.VK_ENTER|.
|
||||
\item To get the keycode, use \verb|e.getKeyCode()|.
|
||||
\item For our game applications, our application class will implement both \verb|KeyListener| \& \verb|Runnable|.
|
||||
\item Note the extra import: \verb|import java.awt.event.*;|.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Loading \& Displaying Raster Images}
|
||||
The constructor of the \verb|ImageIcon| class (defined in \verb|javax.swing| loads an image from disk (\verb|.jpg|. \verb|.gif|, or \verb|.png|) and returns it as a new instance of the \verb|ImageIcon| class.
|
||||
|
||||
The \verb|getImage()| method of this \verb|ImageIcon| object gives you a useable \verb|Image| class object, which can be displayed in your \verb|paint()| method by the \verb|Graphics| class.
|
||||
|
||||
\begin{lstlisting}[language=Java]
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class DisplayRasterImage extends JFrame {
|
||||
// member data
|
||||
private static String workingDirectory;
|
||||
private Image alienImage;
|
||||
|
||||
// constructor
|
||||
public DisplayRasterImage() {
|
||||
// set ip JFrame
|
||||
setBounds(100, 100, 300, 300);
|
||||
setVisible(true);
|
||||
|
||||
// load image from disk. Make sure you have the path right!
|
||||
ImageIcon icon = new ImageIcon(workingDirectory + "/alien_ship_1.png");
|
||||
alienImage = icon.getImage();
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
// application's paint method (may first happen *before* image is finished loading, hence repaint() above
|
||||
public void paint(Graphics g) {
|
||||
// draw a black rectangle on the whole canvas
|
||||
g.setColor(Color.BLACK);
|
||||
g.fillRect(0,0,300,300);
|
||||
|
||||
// display the image (final argument is an "ImageObserver" object)
|
||||
g.drawImage(alienImage, 150, 150, null);
|
||||
}
|
||||
|
||||
// application entry point
|
||||
public static void main(String[] args) {
|
||||
workingDirectory = System.getProperty("user.dir");
|
||||
System.out.println("workingDirectory = " + workingDirectory);
|
||||
DisplayRasterImage d = new DisplayRasterImage();
|
||||
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\section{Lecture 04 - Screen Flicker}
|
||||
Screen flicker is caused by software redrawing a screen out of sync with the screen being refreshed by the graphics hardware,
|
||||
resulting in a half-drawn image occasionally being displayed.
|
||||
|
||||
The solution to screen flicker is to use \textbf{double buffering}.
|
||||
Double buffering involves first rendering all graphics to an offscreen \textit{memory buffer}.
|
||||
Then, when finished drawing a frame of animation, flip the offscreen buffer onscreen furing the ``vertical sync'' period.
|
||||
|
||||
\verb|java.awt| provides a \verb|BufferStrategy| class that applies the best approach based off the capabilities of the
|
||||
computer on which the software is running.
|
||||
|
||||
\subsection{Implementing Double Buffering}
|
||||
\begin{enumerate}
|
||||
\item \verb|import java.awt.image.*;|
|
||||
\item Add a new member variable to the Application class: \verb|private BufferStrategy strategy;|
|
||||
\item In the Application class's constructor method:
|
||||
\begin{lstlisting}[language=Java]
|
||||
createBufferStrategy(2);
|
||||
strategy = getBufferStrategy(); \end{lstlisting}
|
||||
Note that this code should be executed \textbf{after} the JFrame has been displayed, i.e. after \verb|setBounds()|
|
||||
\& \verb|setVisible()|.
|
||||
\item At the start of the \verb|paint(Graphics g)| method, include \verb|g = strategy.getDrawGraphics();| to redirect our
|
||||
drawing calls to the offscreen buffer.
|
||||
\item At the end of the \verb|paint(Graphics g)| method, include \verb|strategy.show();| to indicate that we want to flip
|
||||
the buffers.
|
||||
\end{enumerate}
|
||||
|
||||
\section{Lecture 05 - Finishing Space Invaders}
|
||||
\subsection{Animated 2D Sprites}
|
||||
To animate a 2D sprite, we can simply load two or more images and alternate or cycle between them.
|
||||
For our game, switching image once per second (i.e., every 50$\textsuperscript{th}$ redraw is about right).
|
||||
|
||||
E.g., use this in a modified \verb|Sprite2D| class.
|
||||
\begin{lstlisting}[language=Java]
|
||||
public void paint(Graphics g) {
|
||||
framesDrawn++;
|
||||
if (framesDrawn % 100 < 50) {
|
||||
g.drawImage(myImage, (int) x, (int) y, null);
|
||||
}
|
||||
else {
|
||||
g.drawImage(myImage2, (int) x, (int) y, null);
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Collision Detection}
|
||||
To detect collisions, we cna simply check for overlapping rectangles.
|
||||
\begin{lstlisting}[language=Java]
|
||||
if ( ((x1<x2 && x1+w1>x2) ||(x2<x1 && x2+w2>x1) ) && ( (y1<y2 && y1+h1>y2 ) || (y2<y1 && y2 + h2>y1) ) )
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Game States}
|
||||
Games normally have at least two high-level ``states'', i.e., is the game in progress or are we currently displaying
|
||||
a menu before the game starts (or after it finishes)?
|
||||
To do this, we can simply add a boolean member to the application class: \verb|isGameInProgress|.
|
||||
Depending on the value of this, we can handle various things differently:
|
||||
\begin{itemize}
|
||||
\item Keypresses.
|
||||
\item The \verb|paint()| method.
|
||||
\item The thread's game loop.
|
||||
\end{itemize}
|
||||
|
||||
\section{Lecture 06 - Conway's Game of Life}
|
||||
\subsection{Mouse Events}
|
||||
Mouse events notify when the user uses the mouse (or similar input device) to interact with a component.
|
||||
Mouse events occur when the pointer enters or exits a component's onscreen area and when the user presses or releases one of the mouse buttons.
|
||||
|
||||
Additional events such as mouse movement \& the mouse wheel can be handled by implementing the \verb|MouseMotionListener|
|
||||
and \verb|MouseWheelListener| interfaces.
|
||||
\begin{enumerate}
|
||||
\item Have your class implement \verb|MouseListener|.
|
||||
\item Add \verb|addMouseListener(this);| to the clas constructor.
|
||||
\item Implement the methods below:
|
||||
\begin{lstlisting}[language=Java]
|
||||
// mouse events which must be implemented for MouseListener
|
||||
public void mousePressed(MouseEvent e) { }
|
||||
public void mouseReleased(MouseEvent e) { }
|
||||
public void mouseEntered(MouseEvent e) { }
|
||||
public void mouseExited(MouseEvent e) { }
|
||||
public void mouseClicked(MouseEvent e) { }
|
||||
\end{lstlisting}
|
||||
\end{enumerate}
|
||||
|
||||
\subsection{Conway's Game of Life: Rules}
|
||||
\verb|private boolean gameState[][][] new boolean[40][40][2];|
|
||||
|
||||
\begin{enumerate}
|
||||
\item Any live cell with fewer than two live neighbours dies, as if caused by under-population.
|
||||
\item Any live cell with two or three live neighbours lives on to the next generation.
|
||||
\item Any live cell with more than three live neighbours dies, as if by overcrowding.
|
||||
\item Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
|
||||
\end{enumerate}
|
||||
|
||||
Each generation (iteration) of the game is created by applying the above rules simultaneously to every cell in its
|
||||
preceding generation: births \& deaths occur simultaneously.
|
||||
To implement this properly, we will need to have two separate game states in memory:
|
||||
\begin{itemize}
|
||||
\item One is the ``front buffer'' that we are currently displaying, and which we are checking the above rules on.
|
||||
\item The other is the ``back buffer'' that we're applying the results of the rules to.
|
||||
\item The ``back buffer'' will be switched to the ``front'' after applying the rules to every cell.
|
||||
\end{itemize}
|
||||
|
||||
We will check the eight neighbours of each cell as follows:
|
||||
\begin{lstlisting}[language=java]
|
||||
for (int x=0;x<40;x++) {
|
||||
for (int y=0;y<40;y++) {
|
||||
// count the live neighbours of cell [x][y][0]
|
||||
for (int xx=-1;xx<=1;xx++) {
|
||||
for (int yy=-1;yy<=1;yy++) {
|
||||
if (xx!=0 || yy!=0) {
|
||||
// check cell [x+xx][y+yy][0]
|
||||
// but.. what if x+xx==-1, etc. ?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Note that we need to define the neighbours for cells at the edges of the map.
|
||||
The usual procedure is to ``wrap around'' to the opposite side.
|
||||
|
||||
\subsection{Another Example of a Cellular Automata Algorithm in Use}
|
||||
The image below is of an algorithmically-generated cave-like structure, for use in a 2D computer game.
|
||||
Each of the cells, laid out in a 60x30 grid, either has a wall (denoted by \verb|#|) or a floor (denoted by \verb|.|).
|
||||
|
||||
The cellular automata algorithm which generated this output uses the following steps:
|
||||
\begin{itemize}
|
||||
\item For each cell, randomly define it as: wall (60\% chance) or floor (40\% chance).
|
||||
\item Perform the following procedure four times: Calculate the number of wall neighbours for each cell, and
|
||||
define each cell which has at least 5 neighbouring wall cells, as a wall cell itself.
|
||||
Otherwise (i.e., if it has less than 5 wall neighbours), define it as a floor cell.
|
||||
\end{itemize}
|
||||
|
||||
\begin{center}
|
||||
\includegraphics[width=0.6\textwidth]{cave.png}
|
||||
\end{center}
|
||||
|
||||
\section{Week 8}
|
||||
\subsection{Reading from Text Files}
|
||||
The \verb|java.io| provides file handling classes:
|
||||
\begin{itemize}
|
||||
\item \verb|FileReader| to read from a text file.
|
||||
\item \verb|BufferedFileReader| to read from a text file more efficiently (reads larger blocks \& buffers/caches them).
|
||||
\begin{itemize}
|
||||
\item \textit{Exception handling is required.}
|
||||
\item Uses the \verb|FileReader| class constructor to open a file.
|
||||
\item Uses the \verb|readLine()| method to read a line of text (which returns a \verb|String|).
|
||||
\item Uses the \verb|close()| method to close the file.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
Sample code that reads just one line from the file (stopping at the end of the file or when a carriage return is encountered):
|
||||
\begin{lstlisting}[language=java]
|
||||
String filename = "C:\\Users\\Sam\\Desktop\\lifegame.txt";
|
||||
String textinput = null;
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(filename));
|
||||
textinput = reader.readLine();
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e) { }
|
||||
\end{lstlisting}
|
||||
|
||||
Sample code that reads all the carriage return-separated lines from a file:
|
||||
\begin{lstlisting}[language=java]
|
||||
String line=null;
|
||||
String filename = "C:\\Users\\Sam\\Desktop\\lifegame.txt";
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(filename));
|
||||
do {
|
||||
try {
|
||||
line = reader.readLine();
|
||||
// do something with String here!
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
while (line != null);
|
||||
|
||||
reader.close();
|
||||
|
||||
} catch (IOException e) { }
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Writing to Text Files}
|
||||
Use the \verb|FileWriter| \& \verb|BufferedWriter| classes:
|
||||
|
||||
\verb|BufferedWriter|:
|
||||
\begin{enumerate}
|
||||
\item Use the \verb|FileWriter| class constructor to open a file.
|
||||
\item Use the \verb|write(String s)| method to write a line to the file (with a CR appended automatically).
|
||||
\item Use the \verb|close()| method to close the file.
|
||||
\end{enumerate}
|
||||
|
||||
E.g., to write a single String to a file:
|
||||
\begin{lstlisting}[language=java]
|
||||
String filename = "C:\\Users\\Sam\\Desktop\\lifegame.txt";
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
|
||||
writer.write(outputtext);
|
||||
writer.close();
|
||||
}
|
||||
catch (IOException e) { }
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Handling Mouse Motion Events}
|
||||
In addition to mouse button events, we can also receive mouse \textit{movement} events.
|
||||
Have the class implement the \verb|MouseMotionListener| interface as well as \verb|MouseListener|.
|
||||
In the application class constructor have: \verb|addMouseMotionListener(this);|.
|
||||
Add these methods (receives the same data as the mouse events we have already seeen):
|
||||
\begin{lstlisting}[language=Java]
|
||||
public void mouseMoved(MouseEvent e)
|
||||
public void mouseDragged(MouseEvent e)
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
This is useful for making it less tedious to create a new initial game set-up.
|
||||
|
||||
\section{A* Pathfinding}
|
||||
The fundamental operations of the \textbf{A*} algorithm is to traverse a map by exploring promising positions (nodes) beginning at a starting location, witht the goal of finding the best route to a target location.
|
||||
|
||||
Each node has four attributes, other than its position on the map:
|
||||
\begin{itemize}
|
||||
\item $g$ is the cost of getting from the starting node to this node.
|
||||
\item $h$ is the heuristic (estimated) cost of getting from this node to the target node.
|
||||
$h$ is a best guess, since the algorithm does not yet know the actual cost.
|
||||
\item $f$ is the sum of $g$ \& $h$, and is the algorithm;s best current estimate as to the total cost of travelling from the starting location to the target location via this node.
|
||||
\item \textit{parent} is the identity of the node which connected to this node along a potential solution path.
|
||||
\end{itemize}
|
||||
|
||||
The algorithm maintains two lists of nodes: the \textbf{open} list \& the \textbf{closed} list.
|
||||
\begin{itemize}
|
||||
\item The open list consists of nodes to which the algorithm has already found a route, i.e. one of its connected neighbours has been evaluated (\textit{expanded}) but which have not yet themselves been expanded.
|
||||
\item The closed list consists of nodes that have been expanded and which therefore should not be re-visited.
|
||||
\end{itemize}
|
||||
|
||||
Progress is made by identifying the most promising node in the open list, i.e., the one with the lowest $f$ value, and expanging it by adding each of its connected neighbours to the open list, unless they are
|
||||
already closed.
|
||||
As nodes are expanded, they are moved to the closed list.
|
||||
As nodes are added to the open list, their $f$, $g$, $h$, \& \textit{parent} values are recorded.
|
||||
The $g$ value of a node is, of course, equal to the $g$ value of its parent plus the cost of moving from the parent to the node itself.
|
||||
|
||||
\begin{center}
|
||||
\includegraphics[width=0.7\textwidth]{astar.png}
|
||||
\end{center}
|
||||
|
||||
\subsection{Implementing A* Pathfinding}
|
||||
|
||||
|
||||
\bibliographystyle{unsrtnat}
|
||||
\bibliography{references}
|
||||
\end{document}
|
||||
|
BIN
second/semester2/CT255/Notes/images/astar.png
Normal file
After Width: | Height: | Size: 150 KiB |
BIN
second/semester2/CT255/Notes/images/cave.png
Normal file
After Width: | Height: | Size: 53 KiB |
264
second/semester2/CT255/Notes/report.sty
Normal file
@ -0,0 +1,264 @@
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
|
||||
\ProcessOptions\relax
|
||||
|
||||
% fonts
|
||||
\renewcommand{\rmdefault}{ptm}
|
||||
\renewcommand{\sfdefault}{phv}
|
||||
|
||||
% set page geometry
|
||||
\usepackage[verbose=true,letterpaper]{geometry}
|
||||
\AtBeginDocument{
|
||||
\newgeometry{
|
||||
textheight=9in,
|
||||
textwidth=6.5in,
|
||||
top=1in,
|
||||
headheight=14pt,
|
||||
headsep=25pt,
|
||||
footskip=30pt
|
||||
}
|
||||
}
|
||||
|
||||
\widowpenalty=10000
|
||||
\clubpenalty=10000
|
||||
\flushbottom
|
||||
\sloppy
|
||||
|
||||
|
||||
|
||||
\newcommand{\headeright}{Ph.D. Confirmation Report}
|
||||
\newcommand{\undertitle}{Ph.D. Confirmation Report}
|
||||
\newcommand{\shorttitle}{\@title}
|
||||
|
||||
\usepackage{fancyhdr}
|
||||
\fancyhf{}
|
||||
\pagestyle{fancy}
|
||||
\renewcommand{\headrulewidth}{0.4pt}
|
||||
\fancyheadoffset{0pt}
|
||||
\rhead{\scshape \footnotesize \headeright}
|
||||
\chead{\shorttitle}
|
||||
\cfoot{\thepage}
|
||||
|
||||
|
||||
%Handling Keywords
|
||||
\def\keywordname{{\bfseries \emph{Keywords}}}%
|
||||
\def\keywords#1{\par\addvspace\medskipamount{\rightskip=0pt plus1cm
|
||||
\def\and{\ifhmode\unskip\nobreak\fi\ $\cdot$
|
||||
}\noindent\keywordname\enspace\ignorespaces#1\par}}
|
||||
|
||||
% font sizes with reduced leading
|
||||
\renewcommand{\normalsize}{%
|
||||
\@setfontsize\normalsize\@xipt\@xiipt
|
||||
\abovedisplayskip 7\p@ \@plus 2\p@ \@minus 5\p@
|
||||
\abovedisplayshortskip \z@ \@plus 3\p@
|
||||
\belowdisplayskip \abovedisplayskip
|
||||
\belowdisplayshortskip 4\p@ \@plus 3\p@ \@minus 3\p@
|
||||
}
|
||||
\normalsize
|
||||
\renewcommand{\small}{%
|
||||
\@setfontsize\small\@xpt\@xipt
|
||||
\abovedisplayskip 6\p@ \@plus 1.5\p@ \@minus 4\p@
|
||||
\abovedisplayshortskip \z@ \@plus 2\p@
|
||||
\belowdisplayskip \abovedisplayskip
|
||||
\belowdisplayshortskip 3\p@ \@plus 2\p@ \@minus 2\p@
|
||||
}
|
||||
\renewcommand{\footnotesize}{\@setfontsize\footnotesize\@ixpt\@xpt}
|
||||
\renewcommand{\scriptsize}{\@setfontsize\scriptsize\@viipt\@viiipt}
|
||||
\renewcommand{\tiny}{\@setfontsize\tiny\@vipt\@viipt}
|
||||
\renewcommand{\large}{\@setfontsize\large\@xiipt{14}}
|
||||
\renewcommand{\Large}{\@setfontsize\Large\@xivpt{16}}
|
||||
\renewcommand{\LARGE}{\@setfontsize\LARGE\@xviipt{20}}
|
||||
\renewcommand{\huge}{\@setfontsize\huge\@xxpt{23}}
|
||||
\renewcommand{\Huge}{\@setfontsize\Huge\@xxvpt{28}}
|
||||
|
||||
% sections with less space
|
||||
\providecommand{\section}{}
|
||||
\renewcommand{\section}{%
|
||||
\@startsection{section}{1}{\z@}%
|
||||
{-2.0ex \@plus -0.5ex \@minus -0.2ex}%
|
||||
{ 1.5ex \@plus 0.3ex \@minus 0.2ex}%
|
||||
{\large\bf\raggedright}%
|
||||
}
|
||||
\providecommand{\subsection}{}
|
||||
\renewcommand{\subsection}{%
|
||||
\@startsection{subsection}{2}{\z@}%
|
||||
{-1.8ex \@plus -0.5ex \@minus -0.2ex}%
|
||||
{ 0.8ex \@plus 0.2ex}%
|
||||
{\normalsize\bf\raggedright}%
|
||||
}
|
||||
\providecommand{\subsubsection}{}
|
||||
\renewcommand{\subsubsection}{%
|
||||
\@startsection{subsubsection}{3}{\z@}%
|
||||
{-1.5ex \@plus -0.5ex \@minus -0.2ex}%
|
||||
{ 0.5ex \@plus 0.2ex}%
|
||||
{\normalsize\bf\raggedright}%
|
||||
}
|
||||
\providecommand{\paragraph}{}
|
||||
\renewcommand{\paragraph}{%
|
||||
\@startsection{paragraph}{4}{\z@}%
|
||||
{1.5ex \@plus 0.5ex \@minus 0.2ex}%
|
||||
{-1em}%
|
||||
{\normalsize\bf}%
|
||||
}
|
||||
\providecommand{\subparagraph}{}
|
||||
\renewcommand{\subparagraph}{%
|
||||
\@startsection{subparagraph}{5}{\z@}%
|
||||
{1.5ex \@plus 0.5ex \@minus 0.2ex}%
|
||||
{-1em}%
|
||||
{\normalsize\bf}%
|
||||
}
|
||||
\providecommand{\subsubsubsection}{}
|
||||
\renewcommand{\subsubsubsection}{%
|
||||
\vskip5pt{\noindent\normalsize\rm\raggedright}%
|
||||
}
|
||||
|
||||
% float placement
|
||||
\renewcommand{\topfraction }{0.85}
|
||||
\renewcommand{\bottomfraction }{0.4}
|
||||
\renewcommand{\textfraction }{0.1}
|
||||
\renewcommand{\floatpagefraction}{0.7}
|
||||
|
||||
\newlength{\@abovecaptionskip}\setlength{\@abovecaptionskip}{7\p@}
|
||||
\newlength{\@belowcaptionskip}\setlength{\@belowcaptionskip}{\z@}
|
||||
|
||||
\setlength{\abovecaptionskip}{\@abovecaptionskip}
|
||||
\setlength{\belowcaptionskip}{\@belowcaptionskip}
|
||||
|
||||
% swap above/below caption skip lengths for tables
|
||||
\renewenvironment{table}
|
||||
{\setlength{\abovecaptionskip}{\@belowcaptionskip}%
|
||||
\setlength{\belowcaptionskip}{\@abovecaptionskip}%
|
||||
\@float{table}}
|
||||
{\end@float}
|
||||
|
||||
% footnote formatting
|
||||
\setlength{\footnotesep }{6.65\p@}
|
||||
\setlength{\skip\footins}{9\p@ \@plus 4\p@ \@minus 2\p@}
|
||||
\renewcommand{\footnoterule}{\kern-3\p@ \hrule width 12pc \kern 2.6\p@}
|
||||
\setcounter{footnote}{0}
|
||||
|
||||
% paragraph formatting
|
||||
\setlength{\parindent}{\z@}
|
||||
\setlength{\parskip }{5.5\p@}
|
||||
|
||||
% list formatting
|
||||
\setlength{\topsep }{4\p@ \@plus 1\p@ \@minus 2\p@}
|
||||
\setlength{\partopsep }{1\p@ \@plus 0.5\p@ \@minus 0.5\p@}
|
||||
\setlength{\itemsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@}
|
||||
\setlength{\parsep }{2\p@ \@plus 1\p@ \@minus 0.5\p@}
|
||||
\setlength{\leftmargin }{3pc}
|
||||
\setlength{\leftmargini }{\leftmargin}
|
||||
\setlength{\leftmarginii }{2em}
|
||||
\setlength{\leftmarginiii}{1.5em}
|
||||
\setlength{\leftmarginiv }{1.0em}
|
||||
\setlength{\leftmarginv }{0.5em}
|
||||
\def\@listi {\leftmargin\leftmargini}
|
||||
\def\@listii {\leftmargin\leftmarginii
|
||||
\labelwidth\leftmarginii
|
||||
\advance\labelwidth-\labelsep
|
||||
\topsep 2\p@ \@plus 1\p@ \@minus 0.5\p@
|
||||
\parsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@
|
||||
\itemsep \parsep}
|
||||
\def\@listiii{\leftmargin\leftmarginiii
|
||||
\labelwidth\leftmarginiii
|
||||
\advance\labelwidth-\labelsep
|
||||
\topsep 1\p@ \@plus 0.5\p@ \@minus 0.5\p@
|
||||
\parsep \z@
|
||||
\partopsep 0.5\p@ \@plus 0\p@ \@minus 0.5\p@
|
||||
\itemsep \topsep}
|
||||
\def\@listiv {\leftmargin\leftmarginiv
|
||||
\labelwidth\leftmarginiv
|
||||
\advance\labelwidth-\labelsep}
|
||||
\def\@listv {\leftmargin\leftmarginv
|
||||
\labelwidth\leftmarginv
|
||||
\advance\labelwidth-\labelsep}
|
||||
\def\@listvi {\leftmargin\leftmarginvi
|
||||
\labelwidth\leftmarginvi
|
||||
\advance\labelwidth-\labelsep}
|
||||
|
||||
% create title
|
||||
\providecommand{\maketitle}{}
|
||||
\renewcommand{\maketitle}{%
|
||||
\par
|
||||
\begingroup
|
||||
\renewcommand{\thefootnote}{\fnsymbol{footnote}}
|
||||
% for perfect author name centering
|
||||
\renewcommand{\@makefnmark}{\hbox to \z@{$^{\@thefnmark}$\hss}}
|
||||
% The footnote-mark was overlapping the footnote-text,
|
||||
% added the following to fix this problem (MK)
|
||||
\long\def\@makefntext##1{%
|
||||
\parindent 1em\noindent
|
||||
\hbox to 1.8em{\hss $\m@th ^{\@thefnmark}$}##1
|
||||
}
|
||||
\thispagestyle{empty}
|
||||
\@maketitle
|
||||
\@thanks
|
||||
%\@notice
|
||||
\endgroup
|
||||
\let\maketitle\relax
|
||||
\let\thanks\relax
|
||||
}
|
||||
|
||||
% rules for title box at top of first page
|
||||
\newcommand{\@toptitlebar}{
|
||||
\hrule height 2\p@
|
||||
\vskip 0.25in
|
||||
\vskip -\parskip%
|
||||
}
|
||||
\newcommand{\@bottomtitlebar}{
|
||||
\vskip 0.29in
|
||||
\vskip -\parskip
|
||||
\hrule height 2\p@
|
||||
\vskip 0.09in%
|
||||
}
|
||||
|
||||
% create title (includes both anonymized and non-anonymized versions)
|
||||
\providecommand{\@maketitle}{}
|
||||
\renewcommand{\@maketitle}{%
|
||||
\vbox{%
|
||||
\hsize\textwidth
|
||||
\linewidth\hsize
|
||||
\vskip 0.8in
|
||||
\@toptitlebar
|
||||
\centering
|
||||
{\LARGE\sc \@title\par}
|
||||
\@bottomtitlebar
|
||||
\vskip 0.5in
|
||||
\textsc{\Large\undertitle}\\
|
||||
\vskip 2.0in
|
||||
\def\And{%
|
||||
\end{tabular}\hfil\linebreak[0]\hfil%
|
||||
\begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\ignorespaces%
|
||||
}
|
||||
\def\AND{%
|
||||
\end{tabular}\hfil\linebreak[4]\hfil%
|
||||
\begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\large\ignorespaces%
|
||||
}
|
||||
\begin{tabular}[t]{c}\bf\rule{\z@}{24\p@}\Large\@author\end{tabular}%
|
||||
\vskip 1.0in \@minus 0.1in \center{\large\@date} \vskip 0.2in
|
||||
}
|
||||
}
|
||||
|
||||
% add conference notice to bottom of first page
|
||||
\newcommand{\ftype@noticebox}{8}
|
||||
\newcommand{\@notice}{%
|
||||
% give a bit of extra room back to authors on first page
|
||||
\enlargethispage{2\baselineskip}%
|
||||
\@float{noticebox}[b]%
|
||||
\footnotesize\@noticestring%
|
||||
\end@float%
|
||||
}
|
||||
|
||||
% abstract styling
|
||||
\renewenvironment{abstract}
|
||||
{
|
||||
\centerline
|
||||
{\large \bfseries \scshape Abstract}
|
||||
\begin{quote}
|
||||
}
|
||||
{
|
||||
\end{quote}
|
||||
}
|
||||
|
||||
\endinput
|
||||
|