Initial commit
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.idea/*
|
||||||
|
*.iml
|
||||||
|
out/*
|
106
src/Engine/CollisionUtil.java
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package Engine;
|
||||||
|
|
||||||
|
import Sprites.Sprite;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.PixelGrabber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 12/19/15.
|
||||||
|
*/
|
||||||
|
public class CollisionUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a Sprite is colliding with another Sprite.
|
||||||
|
* @param otherSprite The Sprite to check a collission with.
|
||||||
|
* @param thisSprite another sprite
|
||||||
|
* @return true if the Sprites collide, otherwise false.
|
||||||
|
*/
|
||||||
|
public static boolean collidesWith(Sprite thisSprite, Sprite otherSprite) {
|
||||||
|
boolean isColliding=false;
|
||||||
|
|
||||||
|
Rectangle r1 = thisSprite.getBounds();
|
||||||
|
Rectangle r2 = otherSprite.getBounds();
|
||||||
|
|
||||||
|
r1.intersection(r2);
|
||||||
|
|
||||||
|
if(intersection(r1, r2)) {
|
||||||
|
isColliding = pixelPerfectCollision(thisSprite, otherSprite, r1, r2);
|
||||||
|
}
|
||||||
|
return isColliding;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean intersection(Rectangle r, Rectangle d) {
|
||||||
|
int rect1x = r.x;
|
||||||
|
int rect1y = r.y;
|
||||||
|
int rect1w = r.width;
|
||||||
|
int rect1h = r.height;
|
||||||
|
|
||||||
|
int rect2x = d.x;
|
||||||
|
int rect2y = d.y;
|
||||||
|
int rect2w = d.width;
|
||||||
|
int rect2h = d.height;
|
||||||
|
|
||||||
|
return (rect1x + rect1w >= rect2x &&
|
||||||
|
rect1y + rect1h >= rect2y &&
|
||||||
|
rect1x <= rect2x + rect2w &&
|
||||||
|
rect1y <= rect2y + rect2h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pixelPerfectCollision(); first determines the area where the sprites collides
|
||||||
|
* AKA the collision-rectangle. It then grabs the pixels from both sprites
|
||||||
|
* which are inside the rectangle. It then checks every pixel from the arrays
|
||||||
|
* given by grabPixels();, and if 2 pixels at the same position are opaque,
|
||||||
|
* (alpha value over 0) it will return true. Otherwise it will return false.
|
||||||
|
*/
|
||||||
|
private static boolean pixelPerfectCollision(Sprite sprite1,Sprite sprite2, Rectangle r1, Rectangle r2) {
|
||||||
|
/*
|
||||||
|
* Get the X-values and Y-values for the two coordinates where the sprites collide
|
||||||
|
*/
|
||||||
|
|
||||||
|
int cornerTopX = (r1.x>r2.x)?r1.x:r2.x;
|
||||||
|
int cornerBottomX = ((r1.x+r1.width) < (r2.x+r2.width))?(r1.x+r1.width):(r2.x+r2.width);
|
||||||
|
|
||||||
|
int cornerTopY = (r1.y>r2.y)?r1.y:r2.y;
|
||||||
|
int cornerBottomY = ((r1.y+r1.height) < (r2.y+r2.height))?(r1.y+r1.height):(r2.y+r2.height);
|
||||||
|
|
||||||
|
//Determine the width and height of the collision rectangle
|
||||||
|
int width=cornerBottomX-cornerTopX;
|
||||||
|
int height=cornerBottomY-cornerTopY;
|
||||||
|
|
||||||
|
//Create arrays to hold the pixels
|
||||||
|
int[] pixels1 = new int[width*height];
|
||||||
|
int[] pixels2 = new int[width*height];
|
||||||
|
|
||||||
|
//Create the pixelgrabber and fill the arrays
|
||||||
|
PixelGrabber pg1 = new PixelGrabber(sprite1.getbImage(), cornerTopX-(int)sprite1.getLocX(), cornerTopY-(int)sprite1.getLocY(), width, height, pixels1, 0, width);
|
||||||
|
PixelGrabber pg2 = new PixelGrabber(sprite2.getbImage(), cornerTopX-(int)sprite2.getLocX(), cornerTopY-(int)sprite2.getLocY(), width, height, pixels2, 0, width);
|
||||||
|
|
||||||
|
//Grab the pixels
|
||||||
|
try {
|
||||||
|
pg1.grabPixels();
|
||||||
|
pg2.grabPixels();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
//Logger.getLogger(Sprite.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if pixels at the same spot from both arrays are not transparent.
|
||||||
|
for(int i=0;i<pixels1.length;i++) {
|
||||||
|
int a = (pixels1[i] >>> 24) & 0xff;
|
||||||
|
int a2 = (pixels2[i] >>> 24) & 0xff;
|
||||||
|
|
||||||
|
/* Awesome, we found two pixels in the same spot that aren't
|
||||||
|
* completely transparent! Thus the sprites are colliding!
|
||||||
|
*/
|
||||||
|
if(a > 0 && a2 > 0) return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
243
src/Engine/GameEngine.java
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
package Engine;
|
||||||
|
|
||||||
|
import Sprites.*;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.applet.Applet;
|
||||||
|
import java.applet.AudioClip;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 12/18/15.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class GameEngine extends MouseAdapter {
|
||||||
|
private final int PIPE_ACC = 10, PIPE_WIDTH = 90;
|
||||||
|
public boolean gameOn , gameOver, isFirstGame, canScore;
|
||||||
|
private Bird bird;
|
||||||
|
private Vector<Sprite> pipes; //will save all laser shots and asteroids which are currently on the screen.
|
||||||
|
private int pWidth, pHeight; //panel dimensions
|
||||||
|
private Timer pipeTimer;
|
||||||
|
private Random r;
|
||||||
|
private int score;
|
||||||
|
private BufferedImage sceneImage;
|
||||||
|
|
||||||
|
private Vector<SideScollerBackground> backgrounds;
|
||||||
|
|
||||||
|
private AudioClip themeAudioClip, jumpAudioClip;
|
||||||
|
private final URL jumpURL= getClass().getResource("/Sounds/jump.wav");
|
||||||
|
private final URL themeURL= getClass().getResource("/Sounds/theme.wav");
|
||||||
|
|
||||||
|
public GameEngine(int width, int height){
|
||||||
|
|
||||||
|
|
||||||
|
//initialize variables and load audio\image files.
|
||||||
|
this.canScore = true;
|
||||||
|
this.isFirstGame = true;
|
||||||
|
this.gameOver = true;
|
||||||
|
this.pWidth = width;
|
||||||
|
this.pHeight = height;
|
||||||
|
try {
|
||||||
|
jumpAudioClip = Applet.newAudioClip(jumpURL);
|
||||||
|
themeAudioClip = Applet.newAudioClip(themeURL);
|
||||||
|
}catch (Exception e){
|
||||||
|
jumpAudioClip = null;
|
||||||
|
themeAudioClip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(themeAudioClip != null)
|
||||||
|
themeAudioClip.loop();
|
||||||
|
r = new Random();
|
||||||
|
sceneImage = new BufferedImage(width, height, Image.SCALE_SMOOTH);
|
||||||
|
startNewGame();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize and reset vars and timers to "new game" configuration.
|
||||||
|
*/
|
||||||
|
private void startNewGame(){
|
||||||
|
this.gameOn = true;
|
||||||
|
pipeTimer = new Timer(2000, new PipeTimerListener());
|
||||||
|
backgrounds = new Vector<>();
|
||||||
|
initBackgrounds();
|
||||||
|
initGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup all actors in the game to a new game - reset timer
|
||||||
|
*/
|
||||||
|
private void initGame(){
|
||||||
|
pipes = new Vector<>();
|
||||||
|
|
||||||
|
this.bird = new Bird(100, this.pWidth, this.pHeight, 45);
|
||||||
|
this.score = 0;
|
||||||
|
gameOn = true;
|
||||||
|
pipeTimer.start();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initBackgrounds(){
|
||||||
|
backgrounds.add(new SideScollerBackground(pWidth, pHeight, 2, "skyLine.png", pWidth, pHeight));
|
||||||
|
backgrounds.add(new SideScollerBackground(pWidth, pHeight, 5, "trees.png", pWidth + 50, pHeight));
|
||||||
|
backgrounds.add(new SideScollerBackground(pWidth, pHeight, 10, "ground.png", pWidth, 45));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns score
|
||||||
|
* @return
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
public int getScore(){
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns gameOver flag
|
||||||
|
* @return
|
||||||
|
* boolean
|
||||||
|
*/
|
||||||
|
public boolean isGameOver(){
|
||||||
|
return this.gameOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Pipe on a random position.
|
||||||
|
*/
|
||||||
|
private void createPipe(){
|
||||||
|
int pipeLoc = (r.nextInt(pHeight-40)+40) * -1;
|
||||||
|
pipes.add(new Pipe(pipeLoc, pWidth, pHeight, PIPE_ACC, PIPE_WIDTH, pHeight * 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all sprites, including collision handling.
|
||||||
|
*/
|
||||||
|
public void update(){
|
||||||
|
if(!gameOver) {
|
||||||
|
bird.update();
|
||||||
|
for(int i=0; i<pipes.size(); i++){
|
||||||
|
pipes.elementAt(i).update();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0 ; i < backgrounds.size() ; i++){
|
||||||
|
backgrounds.elementAt(i).update();
|
||||||
|
}
|
||||||
|
collisionHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a collision has occurred.
|
||||||
|
* in case of missile hitting an asteroid - they are both removed.
|
||||||
|
* in case of asteroid hitting the ship - round over.
|
||||||
|
*/
|
||||||
|
private void collisionHandler() {
|
||||||
|
|
||||||
|
//Ikaros - dont fly too high, dont fly to low.
|
||||||
|
if (bird.getLocY() >= pHeight - ( bird.getSWidth() + backgrounds.lastElement().getsHeight())|| bird.getLocY() <= 0) {
|
||||||
|
pipeTimer.stop();
|
||||||
|
gameOver = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//pipe out of screen
|
||||||
|
if (!pipes.isEmpty() && pipes.elementAt(0).getLocX() + PIPE_WIDTH < 0) {
|
||||||
|
canScore = true;
|
||||||
|
pipes.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//pipe vs. bird
|
||||||
|
if (!pipes.isEmpty() && CollisionUtil.collidesWith(bird, pipes.elementAt(0))){
|
||||||
|
gameOver = true;
|
||||||
|
pipeTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(canScore && !pipes.isEmpty() && bird.getLocX() >= pipes.elementAt(0).getLocX() + pipes.elementAt(0).getSWidth()) {
|
||||||
|
score++;
|
||||||
|
canScore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render buffered image.
|
||||||
|
* @param panel
|
||||||
|
* JPanel
|
||||||
|
*/
|
||||||
|
public void render(JPanel panel){
|
||||||
|
sceneImage = new BufferedImage(this.pWidth, this.pHeight, Image.SCALE_FAST); // Empty Scene
|
||||||
|
renderScene(sceneImage.getGraphics(), panel); // Paint new Scene
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws all sprites
|
||||||
|
* @param g
|
||||||
|
* Graphics
|
||||||
|
* @param panel
|
||||||
|
* Jpanel
|
||||||
|
*/
|
||||||
|
public void renderScene(Graphics g, JPanel panel){
|
||||||
|
backgrounds.elementAt(0).drawSprite(g, panel);
|
||||||
|
backgrounds.elementAt(1).drawSprite(g, panel);
|
||||||
|
bird.drawSprite(g, panel);
|
||||||
|
for(int i=0; i<pipes.size(); i++){
|
||||||
|
pipes.elementAt(i).drawSprite(g, panel);
|
||||||
|
}
|
||||||
|
backgrounds.elementAt(2).drawSprite(g, panel);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates an new asteroid each 5 seconds *
|
||||||
|
*/
|
||||||
|
private class PipeTimerListener implements ActionListener{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
createPipe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseClicked(MouseEvent e){
|
||||||
|
if(gameOver){
|
||||||
|
// gameOn = true;
|
||||||
|
this.isFirstGame = false;
|
||||||
|
gameOver = false;
|
||||||
|
initGame();
|
||||||
|
} else {
|
||||||
|
bird.jump();
|
||||||
|
jumpAudioClip.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sceneImage
|
||||||
|
* @return
|
||||||
|
* BufferedImage
|
||||||
|
*/
|
||||||
|
public BufferedImage getScene(){
|
||||||
|
return this.sceneImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
127
src/GamePanels/GamePanel.java
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
package GamePanels;
|
||||||
|
import Engine.*;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
//import java.awt.image.BufferedImage;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 12/18/15.
|
||||||
|
*/
|
||||||
|
public class GamePanel extends JPanel implements Runnable{
|
||||||
|
|
||||||
|
private final URL bgURL= getClass().getResource("/Images/bg.jpg");
|
||||||
|
private final URL gameOverURL= getClass().getResource("/Images/gameOver.png");
|
||||||
|
private final URL startURL= getClass().getResource("/Images/start.png");
|
||||||
|
|
||||||
|
|
||||||
|
// private int width, height;
|
||||||
|
private GameEngine engine;
|
||||||
|
private JLabel lbl_score, lbl_gameOver, lbl_bg, lbl_start;
|
||||||
|
|
||||||
|
private ImageIcon img_bg, img_go, img_start;
|
||||||
|
private Image bg_image;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Constructor.
|
||||||
|
* initializes all objects on panel and creates gameEngine
|
||||||
|
*/
|
||||||
|
public GamePanel(int width, int height){
|
||||||
|
this.setLayout(null);
|
||||||
|
|
||||||
|
this.engine = new GameEngine(width, height);
|
||||||
|
this.addMouseListener(engine);
|
||||||
|
this.setFocusable(true);
|
||||||
|
this.requestFocus();
|
||||||
|
|
||||||
|
//set score label at top left corner
|
||||||
|
this.lbl_score = new JLabel("");
|
||||||
|
lbl_score.setBounds(15,15,width,30);
|
||||||
|
|
||||||
|
|
||||||
|
//set Static background
|
||||||
|
img_bg = new ImageIcon(bgURL);
|
||||||
|
Image tmp_BG = img_bg.getImage();
|
||||||
|
bg_image = tmp_BG.getScaledInstance(width, height, Image.SCALE_SMOOTH);
|
||||||
|
img_bg = new ImageIcon(bg_image);
|
||||||
|
lbl_bg = new JLabel(img_bg);
|
||||||
|
lbl_bg.setBounds(0,0,width,height);
|
||||||
|
|
||||||
|
|
||||||
|
img_start = new ImageIcon(startURL);
|
||||||
|
lbl_start = new JLabel(img_start);
|
||||||
|
lbl_start.setVisible(true);
|
||||||
|
lbl_start.setBounds(0,0,width,height);
|
||||||
|
this.add(lbl_start);
|
||||||
|
|
||||||
|
img_go = new ImageIcon(gameOverURL);
|
||||||
|
lbl_gameOver = new JLabel(img_go);
|
||||||
|
lbl_gameOver.setVisible(false);
|
||||||
|
lbl_gameOver.setBounds(0,0,width,height);
|
||||||
|
this.add(lbl_gameOver);
|
||||||
|
|
||||||
|
|
||||||
|
lbl_score.setFont(new Font("Ariel", Font.BOLD, 24));
|
||||||
|
lbl_score.setForeground(Color.BLACK);
|
||||||
|
this.add(lbl_score);
|
||||||
|
repaint();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
while(engine.gameOn){
|
||||||
|
engine.update();
|
||||||
|
|
||||||
|
//check if game is over and draw labels accordingly
|
||||||
|
if(engine.isGameOver()){
|
||||||
|
if(!engine.isFirstGame)
|
||||||
|
this.lbl_gameOver.setVisible(true);
|
||||||
|
}else{
|
||||||
|
this.lbl_gameOver.setVisible(false);
|
||||||
|
lbl_start.setVisible(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
//render graphics
|
||||||
|
engine.render(this);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
repaint();
|
||||||
|
|
||||||
|
//sleep for other processes to take control
|
||||||
|
try {
|
||||||
|
Thread.sleep(20);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotify(){
|
||||||
|
super.addNotify();
|
||||||
|
(new Thread(this)).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void paintComponent(Graphics g){
|
||||||
|
super.paintComponent(g);
|
||||||
|
Graphics2D g2d = (Graphics2D)g;
|
||||||
|
|
||||||
|
g.drawImage(bg_image, 0, 0, this); //draw the background
|
||||||
|
|
||||||
|
g2d.drawImage(engine.getScene(),0,0,this); //Draw the scene
|
||||||
|
|
||||||
|
//Some labels - Score & countDown
|
||||||
|
lbl_score.setText("SCORE : " + engine.getScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
BIN
src/Images/bg.jpg
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/Images/birdSprite.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
src/Images/gameOver.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
src/Images/ground.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
src/Images/pipe.png
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
src/Images/skyLine.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
src/Images/start.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
src/Images/trees.png
Normal file
After Width: | Height: | Size: 297 KiB |
3
src/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: Main
|
||||||
|
|
18
src/Main.java
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import javax.swing.*;
|
||||||
|
import GamePanels.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 12/18/15.
|
||||||
|
*/
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String args[]){
|
||||||
|
|
||||||
|
JFrame frame = new JFrame("Flappy Angry Birds");
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setSize(1200, 600);
|
||||||
|
frame.setResizable(false);
|
||||||
|
frame.add(new GamePanel(1200, 600));
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
BIN
src/Sounds/jump.wav
Normal file
BIN
src/Sounds/theme.wav
Normal file
31
src/Sprites/Bird.java
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package Sprites;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 22/01/2016.
|
||||||
|
*/
|
||||||
|
public class Bird extends Sprite {
|
||||||
|
|
||||||
|
|
||||||
|
public Bird(int xPosition, int pWidth, int pHeight, int size){
|
||||||
|
super(xPosition, pHeight/2, pWidth, pHeight, 0, "birdSprite.png", 0 ,size, size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
if(acceleration > -10 ) {
|
||||||
|
acceleration--;
|
||||||
|
}
|
||||||
|
locY -= acceleration;
|
||||||
|
if(angle <= 45)
|
||||||
|
angle += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jump() {
|
||||||
|
this.acceleration = 10;
|
||||||
|
angle = -45;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
18
src/Sprites/Pipe.java
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package Sprites;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 23/01/2016.
|
||||||
|
*/
|
||||||
|
public class Pipe extends Sprite {
|
||||||
|
|
||||||
|
|
||||||
|
public Pipe(int y, int w, int h, int acc, int sWidth, int sHeight) {
|
||||||
|
super(w + sWidth, y, w, h, acc, "pipe.png", 0, sWidth, sHeight);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
locX -= acceleration;
|
||||||
|
}
|
||||||
|
}
|
61
src/Sprites/SideScollerBackground.java
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package Sprites;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 23/01/2016.
|
||||||
|
*/
|
||||||
|
public class SideScollerBackground extends Sprite {
|
||||||
|
|
||||||
|
private int locXCopy;
|
||||||
|
|
||||||
|
public SideScollerBackground(int w, int h, int acc, String imgName, int sWidth, int sHeight) {
|
||||||
|
super(0, 0, w, h, acc, imgName, 0, sWidth, sHeight);
|
||||||
|
|
||||||
|
locXCopy = pWidth;
|
||||||
|
if(sHeight != pHeight){
|
||||||
|
locY = pHeight-sHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resizes image to a set size
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void setImageDimensions()
|
||||||
|
{
|
||||||
|
Image tmp = bImage.getScaledInstance(sWidth, sHeight, Image.SCALE_SMOOTH);
|
||||||
|
BufferedImage bi = new BufferedImage(sWidth, sHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
||||||
|
Graphics2D g2d = bi.createGraphics();
|
||||||
|
g2d.drawImage(tmp,0,0,null);
|
||||||
|
g2d.dispose();
|
||||||
|
bImage = bi;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
locX -= acceleration;
|
||||||
|
locXCopy -= acceleration;
|
||||||
|
if(locX+pWidth < 0)
|
||||||
|
locX = pWidth;
|
||||||
|
if(locXCopy+pWidth < 0)
|
||||||
|
locXCopy = pWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawSprite(Graphics g, JPanel p){
|
||||||
|
super.drawSprite(g,p);
|
||||||
|
g.drawImage(bImage, locXCopy, locY, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
159
src/Sprites/Sprite.java
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
package Sprites;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class Sprite {
|
||||||
|
protected BufferedImage bImage;
|
||||||
|
protected int imageWidth, imageHeight; // image dimensions
|
||||||
|
protected URL imagePath;
|
||||||
|
protected int locX, locY;
|
||||||
|
protected int acceleration;
|
||||||
|
protected int pWidth, pHeight; // panel's dimensions
|
||||||
|
protected int sWidth, sHeight;
|
||||||
|
|
||||||
|
protected double angle;
|
||||||
|
|
||||||
|
|
||||||
|
public Sprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight)
|
||||||
|
{
|
||||||
|
this.imagePath = getClass().getResource("/Images/"+imgName);
|
||||||
|
this.sWidth = sWidth;
|
||||||
|
this.sHeight = sHeight;
|
||||||
|
locX = x;
|
||||||
|
locY = y;
|
||||||
|
acceleration = acc;
|
||||||
|
pWidth = w;
|
||||||
|
pHeight = h;
|
||||||
|
this.angle = angle;
|
||||||
|
|
||||||
|
//load image from source files
|
||||||
|
try {
|
||||||
|
bImage = ImageIO.read(imagePath);
|
||||||
|
}catch (IOException pin){
|
||||||
|
pin.printStackTrace();
|
||||||
|
bImage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setImageDimensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resizes image to a set size
|
||||||
|
*/
|
||||||
|
protected void setImageDimensions()
|
||||||
|
{
|
||||||
|
Image tmp = bImage.getScaledInstance(sWidth, sHeight, Image.SCALE_SMOOTH);
|
||||||
|
BufferedImage bi = new BufferedImage(sWidth, sHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
||||||
|
Graphics2D g2d = bi.createGraphics();
|
||||||
|
g2d.drawImage(tmp,0,0,null);
|
||||||
|
g2d.dispose();
|
||||||
|
bImage = bi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract method to update sprite.
|
||||||
|
*/
|
||||||
|
public abstract void update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite x position
|
||||||
|
* @return
|
||||||
|
* double
|
||||||
|
*/
|
||||||
|
public double getLocX() {return locX;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite y position
|
||||||
|
* @return
|
||||||
|
* double
|
||||||
|
*/
|
||||||
|
public double getLocY() {return locY;}
|
||||||
|
|
||||||
|
public int getSWidth() {return sWidth;}
|
||||||
|
|
||||||
|
public int getsHeight() {return sHeight;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite acceleration
|
||||||
|
* @return
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
public int getAcceleration() {return acceleration;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite size
|
||||||
|
* @return
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
public BufferedImage getbImage() {return bImage;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns image width
|
||||||
|
* @return
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
public int getImageWidth() {return imageWidth;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns image height
|
||||||
|
* @return
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
public int getImageHeight() {return imageHeight;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite angle
|
||||||
|
* @return
|
||||||
|
* double
|
||||||
|
*/
|
||||||
|
public double getAngle() {return angle;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns shape location and dimensions as a Rectangle.
|
||||||
|
* @return
|
||||||
|
* Rectangle
|
||||||
|
*/
|
||||||
|
public Rectangle getBounds() {
|
||||||
|
return new Rectangle((int)locX, (int)locY, sWidth, sHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* its not a bug it's a feature. actually it just moves a shape that goes beyond the screen to the other side.
|
||||||
|
*/
|
||||||
|
protected void outOfScreeFix(){
|
||||||
|
if(locX < 0 - sWidth)
|
||||||
|
locX = pWidth;
|
||||||
|
else if (locX > pWidth+sWidth)
|
||||||
|
locX = 0-sWidth;
|
||||||
|
|
||||||
|
if(locY < 0 - sHeight)
|
||||||
|
locY = pHeight;
|
||||||
|
else if(locY > pHeight+sHeight)
|
||||||
|
locY = 0-sHeight ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abstract method for drawing sprite.
|
||||||
|
* @param g
|
||||||
|
* @param p
|
||||||
|
*/
|
||||||
|
public void drawSprite(Graphics g, JPanel p){
|
||||||
|
Graphics2D g2d = (Graphics2D)g;
|
||||||
|
g2d.rotate(Math.toRadians(angle), locX + (bImage.getWidth()/2), locY + (bImage.getHeight()/2));
|
||||||
|
g.drawImage(bImage, locX, locY, p);
|
||||||
|
g2d.rotate(-1*Math.toRadians(angle), locX + (bImage.getWidth()/2), locY + (bImage.getHeight()/2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|