Initial commit - Skeleton of the game
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.idea/
|
||||||
|
out/
|
||||||
|
*.iml
|
55
src/com/sagi/dayan/Games/Elements/AnimatedDemoSprite.java
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/10/16.
|
||||||
|
*/
|
||||||
|
public class AnimatedDemoSprite extends AnimatedSprite {
|
||||||
|
|
||||||
|
private int timerCouner = 0;
|
||||||
|
protected Timer t;
|
||||||
|
|
||||||
|
public AnimatedDemoSprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight) {
|
||||||
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
|
setScreenLoop(true);
|
||||||
|
animations.add(new Animation("animatedSample2.png", 16, 2000));
|
||||||
|
t = new Timer(1 * 1000, new TimerTick());
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
locX += acceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFirstAnimation(String spriteSheet) {
|
||||||
|
animations.add(new Animation(spriteSheet, 8, 1 * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TimerTick implements ActionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
if(timerCouner < 5){
|
||||||
|
timerCouner++;
|
||||||
|
}
|
||||||
|
else if(5 <= timerCouner && timerCouner < 7){
|
||||||
|
System.out.println("Explode");
|
||||||
|
timerCouner++;
|
||||||
|
currentAnimation = 1;
|
||||||
|
acceleration = 0;
|
||||||
|
}else{
|
||||||
|
currentAnimation = 0;
|
||||||
|
timerCouner = 0;
|
||||||
|
acceleration = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
134
src/com/sagi/dayan/Games/Elements/AnimatedSprite.java
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/10/16.
|
||||||
|
*/
|
||||||
|
public abstract class AnimatedSprite extends Sprite {
|
||||||
|
protected Vector<Animation> animations;
|
||||||
|
protected int currentAnimation;
|
||||||
|
|
||||||
|
|
||||||
|
public AnimatedSprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight) {
|
||||||
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
|
animations = new Vector<>();
|
||||||
|
initFirstAnimation(imgName);
|
||||||
|
currentAnimation = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void initFirstAnimation(String spriteSheet);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawSprite(Graphics g, JPanel p) {
|
||||||
|
if(animations.size() == 0)
|
||||||
|
return;
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
g2d.rotate(Math.toRadians(angle), locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
|
g.drawImage(animations.get(currentAnimation).getCurrentFrame(), locX, locY, p);
|
||||||
|
g2d.rotate(-1 * Math.toRadians(angle), locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
|
if(screenLoop) {
|
||||||
|
drawScreenLoopFix(g, p);
|
||||||
|
outOfScreeFix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawScreenLoopFix(Graphics g, JPanel p) {
|
||||||
|
bImage = animations.get(currentAnimation).getCurrentFrame();
|
||||||
|
super.drawScreenLoopFix(g,p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentAnimation(int animation){
|
||||||
|
if(animation < 0){
|
||||||
|
throw new IllegalArgumentException("Animation index cant be negative");
|
||||||
|
}else if(animation >= animations.size()){
|
||||||
|
throw new IllegalArgumentException("Number of animations is: "+ animations.size() + 1+". " +animation +"is out the limit");
|
||||||
|
}else{
|
||||||
|
currentAnimation = animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected class Animation {
|
||||||
|
|
||||||
|
private int totalLoopTime;
|
||||||
|
private Vector<AnimationFrame> frames;
|
||||||
|
private int currentFrame;
|
||||||
|
private long startingTime;
|
||||||
|
private BufferedImage spriteSheet;
|
||||||
|
|
||||||
|
public Animation(String spriteSheetName, int numOfFrames, int totalAnimationTime) {
|
||||||
|
this.currentFrame = 0;
|
||||||
|
this.totalLoopTime = 0;
|
||||||
|
this.startingTime = System.currentTimeMillis();
|
||||||
|
this.frames = new Vector<>();
|
||||||
|
|
||||||
|
//load image from source files
|
||||||
|
try {
|
||||||
|
spriteSheet = ImageIO.read(getClass().getResource("/com/sagi/dayan/Games/Images/" + spriteSheetName));
|
||||||
|
} catch (IOException pin) {
|
||||||
|
pin.printStackTrace();
|
||||||
|
spriteSheet = null;
|
||||||
|
}
|
||||||
|
int frameHeight = spriteSheet.getHeight();
|
||||||
|
int frameWidth = spriteSheet.getWidth() / numOfFrames;
|
||||||
|
int currentX = 0;
|
||||||
|
for(int i = 0 ; i < numOfFrames ; i++) {
|
||||||
|
addFrame(spriteSheet.getSubimage(currentX, 0, frameWidth, frameHeight), (double)totalAnimationTime/numOfFrames);
|
||||||
|
currentX += frameWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFrameIndex() { return currentFrame;}
|
||||||
|
|
||||||
|
private void addFrame(BufferedImage image, double frameLength) {
|
||||||
|
frames.add(new AnimationFrame(image, totalLoopTime,frameLength));
|
||||||
|
totalLoopTime += frameLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getCurrentFrame() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long delta = now - startingTime;
|
||||||
|
while( !( frames.get(currentFrame).getStartTime() <= delta && delta < frames.get(currentFrame).getEndTime() ) ){
|
||||||
|
currentFrame++;
|
||||||
|
if(currentFrame >= frames.size()) {
|
||||||
|
currentFrame = 0;
|
||||||
|
startingTime = now;
|
||||||
|
return frames.get(currentFrame).getFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return frames.get(currentFrame).getFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class AnimationFrame {
|
||||||
|
private double startTime, endTime;
|
||||||
|
private BufferedImage frame;
|
||||||
|
|
||||||
|
public AnimationFrame(BufferedImage image, double startTime , double frameLength){
|
||||||
|
this.startTime = startTime;
|
||||||
|
this.endTime = this.startTime + frameLength;
|
||||||
|
this.frame = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getStartTime() { return startTime;}
|
||||||
|
public double getEndTime() { return endTime;}
|
||||||
|
public BufferedImage getFrame() {return frame;}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
19
src/com/sagi/dayan/Games/Elements/Background.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/20/16.
|
||||||
|
*/
|
||||||
|
public class Background extends Sprite {
|
||||||
|
public Background(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight) {
|
||||||
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
|
locX = 0;
|
||||||
|
locY = pHeight - sHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
locY += acceleration;
|
||||||
|
if(locY >= 0)
|
||||||
|
locY = 0;
|
||||||
|
}
|
||||||
|
}
|
64
src/com/sagi/dayan/Games/Elements/DemoSprite.java
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/10/16.
|
||||||
|
*/
|
||||||
|
public class DemoSprite extends Sprite {
|
||||||
|
private final int STOP=0, UP=1, DOWN=-1, TURN_SPEED=10;
|
||||||
|
private final double MAX_SPEED = 6, SLOWING_FACTOR = 0.1;
|
||||||
|
Random r;
|
||||||
|
private double selfAccel;
|
||||||
|
private int direction, turnDirection;
|
||||||
|
int counter = 0;
|
||||||
|
public DemoSprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight) {
|
||||||
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
|
selfRotationSpeed = 5;
|
||||||
|
direction = STOP;
|
||||||
|
turnDirection = STOP;
|
||||||
|
selfAccel = acceleration;
|
||||||
|
setScreenLoop(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
setSpeed();
|
||||||
|
this.angle+=TURN_SPEED*turnDirection;
|
||||||
|
locX += selfAccel * Math.cos(Math.toRadians(angle));
|
||||||
|
locY -= selfAccel * (-1 * Math.sin(Math.toRadians(angle)));
|
||||||
|
System.out.println("locX: " + locX + "\tlocY: "+locY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSpeed(){
|
||||||
|
if (direction == UP && !(selfAccel > MAX_SPEED)){
|
||||||
|
selfAccel+=SLOWING_FACTOR*2;
|
||||||
|
}
|
||||||
|
else if (direction == DOWN && (selfAccel > MAX_SPEED*(-1))){
|
||||||
|
selfAccel-=SLOWING_FACTOR*2;
|
||||||
|
}
|
||||||
|
else { //slowing down
|
||||||
|
if (selfAccel > 0) {
|
||||||
|
selfAccel -= SLOWING_FACTOR;
|
||||||
|
if (selfAccel < 0) {
|
||||||
|
selfAccel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selfAccel < 0) {
|
||||||
|
selfAccel += SLOWING_FACTOR;
|
||||||
|
if (selfAccel > 0) {
|
||||||
|
selfAccel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirection(int direction) {
|
||||||
|
this.direction = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void turnShip(int direction){
|
||||||
|
turnDirection=direction;
|
||||||
|
}
|
||||||
|
}
|
35
src/com/sagi/dayan/Games/Elements/EnemyShip.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/20/16.
|
||||||
|
*/
|
||||||
|
public class EnemyShip extends AnimatedSprite {
|
||||||
|
Timer t;
|
||||||
|
public EnemyShip(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight, ActionListener timerListener) {
|
||||||
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
|
|
||||||
|
t = new Timer(1000,timerListener);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFirstAnimation(String spriteSheet) {
|
||||||
|
animations.add(new Animation("P1Laser.png", 4, 500));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
locX = 200;
|
||||||
|
locY += acceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
20
src/com/sagi/dayan/Games/Elements/MenuBoxSprite.java
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/24/16.
|
||||||
|
*/
|
||||||
|
public class MenuBoxSprite extends AnimatedSprite {
|
||||||
|
public MenuBoxSprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight) {
|
||||||
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFirstAnimation(String spriteSheet) {
|
||||||
|
animations.add(new Animation("menuBox.png", 15, 150));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
22
src/com/sagi/dayan/Games/Elements/Missile.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/20/16.
|
||||||
|
*/
|
||||||
|
public class Missile extends AnimatedSprite {
|
||||||
|
|
||||||
|
|
||||||
|
public Missile(int x, int y, int acc, String imgName) {
|
||||||
|
super(x, y, 0, 0, acc, imgName, 0, 15, 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFirstAnimation(String spriteSheet) {
|
||||||
|
animations.add(new Animation("P1Laser.png", 4, 500));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
locY -= acceleration;
|
||||||
|
}
|
||||||
|
}
|
91
src/com/sagi/dayan/Games/Elements/Player.java
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/20/16.
|
||||||
|
*/
|
||||||
|
public class Player extends AnimatedSprite {
|
||||||
|
private final int NORMAL_ANIMATION = 0, RIGHT_ANIMATION = 1, LEFT_ANIMATION = 2, PADDING_BOTTOM = 35;
|
||||||
|
private int hDirection = 0, vDirection = 0;
|
||||||
|
private String imagePrefix;
|
||||||
|
private boolean ableToFire;
|
||||||
|
private int fireDelay;
|
||||||
|
private long lastFired;
|
||||||
|
|
||||||
|
|
||||||
|
public Player(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight, String imagePrefix) {
|
||||||
|
super(x, y, w, h, acc, imgName, angle, sWidth, sHeight);
|
||||||
|
this.imagePrefix = imagePrefix;
|
||||||
|
initFirstAnimation("");
|
||||||
|
this.ableToFire = true;
|
||||||
|
fireDelay = 100;
|
||||||
|
lastFired = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initFirstAnimation(String spriteSheet) {
|
||||||
|
if(imagePrefix == null)
|
||||||
|
return;
|
||||||
|
System.out.println(imagePrefix);
|
||||||
|
animations.add(new Animation(imagePrefix+"StraighSheet.png", 7, 200));
|
||||||
|
animations.add(new Animation(imagePrefix+"RightSheet.png", 7, 200));
|
||||||
|
animations.add(new Animation(imagePrefix+"LeftSheet.png", 7, 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
if(now - lastFired >= fireDelay){
|
||||||
|
ableToFire = true;
|
||||||
|
}else{
|
||||||
|
ableToFire = false;
|
||||||
|
}
|
||||||
|
locX += vDirection * acceleration;
|
||||||
|
locY -= hDirection * acceleration;
|
||||||
|
if(locX < 0)
|
||||||
|
locX = 0;
|
||||||
|
else if(locX > pWidth - animations.get(currentAnimation).getCurrentFrame().getWidth()){
|
||||||
|
locX = pWidth - animations.get(currentAnimation).getCurrentFrame().getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(locY < 0)
|
||||||
|
locY = 0;
|
||||||
|
else if(locY > pHeight - animations.get(currentAnimation).getCurrentFrame().getHeight() - PADDING_BOTTOM){
|
||||||
|
locY = pHeight - animations.get(currentAnimation).getCurrentFrame().getHeight() - PADDING_BOTTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sethDirection(int direction) {
|
||||||
|
this.hDirection = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setvDirection(int direction) {
|
||||||
|
this.vDirection = direction;
|
||||||
|
if(direction != NORMAL_ANIMATION){
|
||||||
|
currentAnimation = (direction == 1) ? RIGHT_ANIMATION : LEFT_ANIMATION;
|
||||||
|
}else{
|
||||||
|
currentAnimation = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAbleToFire() {
|
||||||
|
return ableToFire;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAbleToFire(boolean ableToFire) {
|
||||||
|
this.ableToFire = ableToFire;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFireDelay() {
|
||||||
|
return fireDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFireDelay(int fireDelay) {
|
||||||
|
this.fireDelay = fireDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateFireTime(){
|
||||||
|
lastFired = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
261
src/com/sagi/dayan/Games/Elements/Sprite.java
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
package com.sagi.dayan.Games.Elements;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
|
||||||
|
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 int selfRotationSpeed;
|
||||||
|
protected double angle;
|
||||||
|
protected boolean screenLoop = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Sprite(int x, int y, int w, int h, int acc, String imgName, double angle, int sWidth, int sHeight) {
|
||||||
|
this.imagePath = getClass().getResource("/com/sagi/dayan/Games/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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocX(int locX) {
|
||||||
|
this.locX = locX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocY(int locY) {
|
||||||
|
this.locY = locY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite y position
|
||||||
|
*
|
||||||
|
* @return double
|
||||||
|
*/
|
||||||
|
public double getLocY() {
|
||||||
|
return locY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite image width
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public int getSWidth() {
|
||||||
|
return sWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns sprite image height
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCenterX() {return locX + (sWidth / 2);}
|
||||||
|
public int getCenterY() {return locY + (sHeight / 2);}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns shape location and dimensions as a Rectangle.
|
||||||
|
*
|
||||||
|
* @return Rectangle
|
||||||
|
*/
|
||||||
|
public Rectangle getBounds() {
|
||||||
|
return new Rectangle((int) locX, (int) locY, sWidth, sHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isScreenLoop() {
|
||||||
|
return screenLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScreenLoop(boolean screenLoop) {
|
||||||
|
this.screenLoop = screenLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(){
|
||||||
|
/**
|
||||||
|
* X: Left Edge
|
||||||
|
*/
|
||||||
|
if(locX < 0 - sWidth)
|
||||||
|
locX = pWidth + locX;
|
||||||
|
/**
|
||||||
|
* X: Right Edge
|
||||||
|
*/
|
||||||
|
else if (locX > pWidth + sWidth)
|
||||||
|
locX = Math.abs(pWidth - (locX + sWidth)) - sWidth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Y: Top Edge
|
||||||
|
*/
|
||||||
|
if(locY < 0 - sHeight)
|
||||||
|
locY = pHeight + locY;
|
||||||
|
/**
|
||||||
|
* Y: Bottom Edge
|
||||||
|
*/
|
||||||
|
else if(locY > pHeight+sHeight)
|
||||||
|
locY = Math.abs(pHeight - (locY + sHeight)) - sHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void drawScreenLoopFix(Graphics g, JPanel p) {
|
||||||
|
Graphics2D g2d = (Graphics2D)g;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Left Edge
|
||||||
|
*/
|
||||||
|
if (locX < 0) {
|
||||||
|
g2d.rotate(Math.toRadians(angle), pWidth + locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
|
g.drawImage(bImage, pWidth + locX, locY, p);
|
||||||
|
g2d.rotate(-1 * Math.toRadians(angle), pWidth + locX + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Right Edge
|
||||||
|
*/
|
||||||
|
if (locX + sWidth > pWidth ) {
|
||||||
|
g2d.rotate(Math.toRadians(angle), Math.abs(pWidth - (locX + sWidth)) - sWidth + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
|
g.drawImage(bImage, Math.abs(pWidth - (locX + sWidth)) - sWidth, locY, p);
|
||||||
|
g2d.rotate(-1 * Math.toRadians(angle), Math.abs(pWidth - (locX + sWidth)) - sWidth + (bImage.getWidth() / 2), locY + (bImage.getHeight() / 2));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Top Edge
|
||||||
|
*/
|
||||||
|
if (locY < 0) {
|
||||||
|
g2d.rotate(Math.toRadians(angle), locX + (bImage.getWidth() / 2), pHeight + locY + (bImage.getHeight() / 2));
|
||||||
|
g.drawImage(bImage, locX , pHeight + locY, p);
|
||||||
|
g2d.rotate(-1 * Math.toRadians(angle), locX + (bImage.getWidth() / 2), pHeight + locY + (bImage.getHeight() / 2));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Bottom Edge
|
||||||
|
*/
|
||||||
|
if ( pHeight < locY + sHeight) {
|
||||||
|
g2d.rotate(Math.toRadians(angle), locX + (bImage.getWidth() / 2), Math.abs(pHeight - (locY + sHeight)) - sHeight+ (bImage.getHeight() / 2));
|
||||||
|
g.drawImage(bImage, locX , Math.abs(pHeight - (locY + sHeight)) - sHeight, p);
|
||||||
|
g2d.rotate(-1 * Math.toRadians(angle), locX + (bImage.getWidth() / 2), Math.abs(pHeight - (locY + sHeight)) - sHeight + (bImage.getHeight() / 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param g
|
||||||
|
*/
|
||||||
|
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));
|
||||||
|
if(screenLoop) {
|
||||||
|
outOfScreeFix();
|
||||||
|
drawScreenLoopFix(g, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
109
src/com/sagi/dayan/Games/Engine/CollisionUtil.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package com.sagi.dayan.Games.Engine;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 12/19/15.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Elements.Sprite;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.PixelGrabber;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
163
src/com/sagi/dayan/Games/Engine/GameEngine.java
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
package com.sagi.dayan.Games.Engine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/8/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Elements.*;
|
||||||
|
import com.sagi.dayan.Games.Stage.*;
|
||||||
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 12/18/15.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class GameEngine {
|
||||||
|
public boolean gameOn , gameOver, isFirstGame;
|
||||||
|
private JFrame frame;
|
||||||
|
private int pWidth, pHeight, numOfPlayers; //panel dimensions
|
||||||
|
private Random r;
|
||||||
|
private Stage stage;
|
||||||
|
private Vector<Scene> scenes;
|
||||||
|
private int currentScene;
|
||||||
|
public static final int PLAYER_WIDTH = 120, PLAYER_HEIGHT = 120;
|
||||||
|
public static final int UP=0,RIGHT=1,DOWN=2, LEFT=3, FIRE=4, SPECIAL=5;
|
||||||
|
|
||||||
|
private int[] p1Controlles = {KeyEvent.VK_UP, KeyEvent.VK_RIGHT, KeyEvent.VK_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_K};
|
||||||
|
private int[] p2Controlles = {KeyEvent.VK_W, KeyEvent.VK_D, KeyEvent.VK_S, KeyEvent.VK_A, KeyEvent.VK_SHIFT};
|
||||||
|
|
||||||
|
private Font gameFont;
|
||||||
|
|
||||||
|
public GameEngine(int width, int height, Stage stage){
|
||||||
|
this.currentScene = 0;
|
||||||
|
this.isFirstGame = true;
|
||||||
|
this.gameOver = true;
|
||||||
|
this.pWidth = width;
|
||||||
|
this.pHeight = height;
|
||||||
|
this.scenes = new Vector<>();
|
||||||
|
this.stage = stage;
|
||||||
|
// scenes.add(new FirstStage(width, height, 2)); // Need to be a menu Scene
|
||||||
|
scenes.add(new MainMenuScene(width, height, this));
|
||||||
|
stage.addKeyListener(scenes.get(currentScene));
|
||||||
|
stage.addMouseListener(scenes.get(currentScene));
|
||||||
|
r = new Random();
|
||||||
|
try{
|
||||||
|
gameFont = Font.createFont(Font.TRUETYPE_FONT,Utils.getFontStream("transformers.ttf"));
|
||||||
|
} catch (FontFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
gameFont = null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
gameFont = null;
|
||||||
|
}
|
||||||
|
startNewGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initialize and reset vars and timers to "new game" configuration.
|
||||||
|
*/
|
||||||
|
private void startNewGame(){
|
||||||
|
this.gameOn = true;
|
||||||
|
initGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup all actors in the game to a new game - reset timer
|
||||||
|
*/
|
||||||
|
private void initGame(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns gameOver flag
|
||||||
|
* @return
|
||||||
|
* boolean
|
||||||
|
*/
|
||||||
|
public boolean isGameOver(){
|
||||||
|
return this.gameOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all sprites, including collision handling.
|
||||||
|
*/
|
||||||
|
public void update(){
|
||||||
|
scenes.get(currentScene).update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(JPanel p) {
|
||||||
|
scenes.get(currentScene).render(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getScene() {
|
||||||
|
return scenes.get(currentScene).getSceneImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeScene(int index) {
|
||||||
|
if (index >= scenes.size()){
|
||||||
|
throw new IllegalArgumentException("Invalid Index. scenes size: "+scenes.size());
|
||||||
|
}
|
||||||
|
stage.removeKeyListener(scenes.get(currentScene));
|
||||||
|
stage.removeMouseListener(scenes.get(currentScene));
|
||||||
|
currentScene = index;
|
||||||
|
stage.addKeyListener(scenes.get(currentScene));
|
||||||
|
stage.addMouseListener(scenes.get(currentScene));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startGame(int numOfPlayers){
|
||||||
|
this.numOfPlayers = numOfPlayers;
|
||||||
|
scenes.add(new FirstStage(pWidth, pHeight, numOfPlayers, this, "-= STAGE 1.0 =-"));
|
||||||
|
changeScene(currentScene+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void goToSettings() {
|
||||||
|
scenes.add(new SettingsMenuScene(pWidth, pHeight, this));
|
||||||
|
changeScene(currentScene+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void goToMainMenu() {
|
||||||
|
|
||||||
|
changeScene(0);
|
||||||
|
for(int i = scenes.size() -1 ; i > 0 ; i--){
|
||||||
|
scenes.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScenesSize(){
|
||||||
|
return scenes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getP1Controlles(){
|
||||||
|
return p1Controlles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getP2Controlles(){
|
||||||
|
return p2Controlles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Font getGameFont() {
|
||||||
|
return gameFont;
|
||||||
|
}
|
||||||
|
}
|
BIN
src/com/sagi/dayan/Games/Fonts/transformers.ttf
Normal file
BIN
src/com/sagi/dayan/Games/Graphics/Settigns menu.xcf
Normal file
BIN
src/com/sagi/dayan/Games/Graphics/main mwnu.xcf
Normal file
BIN
src/com/sagi/dayan/Games/Images/L1-BG.jpg
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
src/com/sagi/dayan/Games/Images/L1-ES1.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
src/com/sagi/dayan/Games/Images/P1Laser.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/com/sagi/dayan/Games/Images/P1LeftSheet.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/com/sagi/dayan/Games/Images/P1RightSheet.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/com/sagi/dayan/Games/Images/P1StraighSheet.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/com/sagi/dayan/Games/Images/P2LeftSheet.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/com/sagi/dayan/Games/Images/P2RightSheet.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/com/sagi/dayan/Games/Images/P2StraighSheet.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/com/sagi/dayan/Games/Images/Settigns_menu.jpg
Normal file
After Width: | Height: | Size: 322 KiB |
BIN
src/com/sagi/dayan/Games/Images/animatedSample.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
src/com/sagi/dayan/Games/Images/animatedSample2.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
src/com/sagi/dayan/Games/Images/emptyImage.png
Normal file
After Width: | Height: | Size: 168 B |
BIN
src/com/sagi/dayan/Games/Images/menu.jpg
Normal file
After Width: | Height: | Size: 319 KiB |
BIN
src/com/sagi/dayan/Games/Images/menu0.png
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
src/com/sagi/dayan/Games/Images/menuBack.jpg
Normal file
After Width: | Height: | Size: 290 KiB |
BIN
src/com/sagi/dayan/Games/Images/menuBox.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
src/com/sagi/dayan/Games/Images/ship2.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
36
src/com/sagi/dayan/Games/Main.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package com.sagi.dayan.Games;
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
|
import com.sagi.dayan.Games.Stage.Stage;
|
||||||
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/8/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static final int WIDTH = 1000, HEIGHT = 1000;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
JFrame frame = new JFrame("Game");
|
||||||
|
frame.setSize(WIDTH, HEIGHT);
|
||||||
|
frame.setResizable(false);
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.add(new Stage(WIDTH, HEIGHT));
|
||||||
|
frame.setVisible(true);
|
||||||
|
frame.setBackground(Color.BLACK);
|
||||||
|
System.out.println(WIDTH + "\t" + (HEIGHT));
|
||||||
|
System.out.println("=========================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
BIN
src/com/sagi/dayan/Games/Sounds/intro.mp3
Normal file
BIN
src/com/sagi/dayan/Games/Sounds/intro.wav
Normal file
BIN
src/com/sagi/dayan/Games/Sounds/introBackup.wav
Normal file
BIN
src/com/sagi/dayan/Games/Sounds/jetSound.wav
Normal file
BIN
src/com/sagi/dayan/Games/Sounds/menuItem.wav
Normal file
BIN
src/com/sagi/dayan/Games/Sounds/menuSelect.wav
Normal file
274
src/com/sagi/dayan/Games/Stage/FirstStage.java
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
package com.sagi.dayan.Games.Stage;
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Elements.Background;
|
||||||
|
import com.sagi.dayan.Games.Elements.EnemyShip;
|
||||||
|
import com.sagi.dayan.Games.Elements.Missile;
|
||||||
|
import com.sagi.dayan.Games.Elements.Player;
|
||||||
|
import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/20/16.
|
||||||
|
*/
|
||||||
|
public class FirstStage extends Scene {
|
||||||
|
protected Vector<Player> players;
|
||||||
|
protected int p1Speed = 10;
|
||||||
|
protected Vector<Missile> missiles;
|
||||||
|
protected Background bg;
|
||||||
|
protected Timer enemyWaveT, enemyT;
|
||||||
|
protected Vector<EnemyShip> enemies;
|
||||||
|
protected int[] yAxisStartingAnimation;
|
||||||
|
protected int startingAnimationIndex;
|
||||||
|
protected boolean isStarted;
|
||||||
|
protected int numOfPlayers;
|
||||||
|
protected Map<Integer, Boolean> keys;
|
||||||
|
protected String title;
|
||||||
|
protected JLabel stageTitle;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public FirstStage(int width, int height, int numOfPlayers, GameEngine engine, String stageTitle){
|
||||||
|
super(width, height, engine);
|
||||||
|
players = new Vector<>();
|
||||||
|
missiles = new Vector<>();
|
||||||
|
isStarted = false;
|
||||||
|
keys = new HashMap<>();
|
||||||
|
yAxisStartingAnimation = new int[]{height + (5*GameEngine.PLAYER_HEIGHT) , height - (4*GameEngine.PLAYER_HEIGHT) , height - (GameEngine.PLAYER_HEIGHT + 15)};
|
||||||
|
startingAnimationIndex = 0;
|
||||||
|
bg = new Background(0,0,width,height, 1, "L1-BG.jpg", 0,1000, 4760);
|
||||||
|
this.numOfPlayers = numOfPlayers;
|
||||||
|
this.title = stageTitle;
|
||||||
|
this.stageTitle = new JLabel(this.title);
|
||||||
|
|
||||||
|
if(numOfPlayers == 1) {
|
||||||
|
players.add(new Player((width / 2) + (GameEngine.PLAYER_WIDTH / 2), yAxisStartingAnimation[startingAnimationIndex], width, height, p1Speed, "emptyImage.png", 0, GameEngine.PLAYER_WIDTH, GameEngine.PLAYER_HEIGHT, "P1"));
|
||||||
|
}else{
|
||||||
|
players.add(new Player((width / 2) + (GameEngine.PLAYER_WIDTH / 2) + GameEngine.PLAYER_WIDTH, yAxisStartingAnimation[startingAnimationIndex], width, height, p1Speed, "emptyImage.png", 0, GameEngine.PLAYER_WIDTH, GameEngine.PLAYER_HEIGHT, "P1"));
|
||||||
|
players.add(new Player((width / 2) + (GameEngine.PLAYER_WIDTH / 2) - GameEngine.PLAYER_WIDTH*3, yAxisStartingAnimation[startingAnimationIndex], width, height, p1Speed, "emptyImage.png", 0, GameEngine.PLAYER_WIDTH, GameEngine.PLAYER_HEIGHT, "P2"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setupKeys();
|
||||||
|
enemies = new Vector<>();
|
||||||
|
enemyWaveT = new Timer(10000, new enemyWaveLaunch());
|
||||||
|
enemyT = new Timer(10000, new enemyLaunch());
|
||||||
|
enemyWaveT.start();
|
||||||
|
|
||||||
|
Utils.playSound("jetSound.wav");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupKeys() {
|
||||||
|
int[] p1 = engine.getP1Controlles();
|
||||||
|
for(int i = 0 ; i < p1.length ; i++){
|
||||||
|
keys.put(p1[i], false);
|
||||||
|
}
|
||||||
|
if(numOfPlayers > 1){
|
||||||
|
int[] p2 = engine.getP2Controlles();
|
||||||
|
for(int i = 0 ; i < p1.length ; i++){
|
||||||
|
keys.put(p2[i], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
|
||||||
|
bg.update();
|
||||||
|
movePlayers();
|
||||||
|
|
||||||
|
if(startingAnimationIndex < 3 && !isStarted){
|
||||||
|
if(startingAnimationIndex == 0){
|
||||||
|
startingAnimationIndex++;
|
||||||
|
}
|
||||||
|
if(players.get(0).getLocY() > yAxisStartingAnimation[startingAnimationIndex] && startingAnimationIndex == 1){
|
||||||
|
for(int i = 0 ; i < players.size() ; i++){
|
||||||
|
players.get(i).setLocY((int)players.get(i).getLocY() - (p1Speed));
|
||||||
|
// players.get(i).update();
|
||||||
|
}
|
||||||
|
if(players.get(0).getLocY() <= yAxisStartingAnimation[startingAnimationIndex]){
|
||||||
|
startingAnimationIndex++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
|
||||||
|
for(int i = 0 ; i < players.size() ; i++){
|
||||||
|
players.get(i).setLocY((int)players.get(i).getLocY() + (p1Speed - 5));
|
||||||
|
// players.get(i).update();
|
||||||
|
}
|
||||||
|
if(players.get(0).getLocY() >= yAxisStartingAnimation[startingAnimationIndex]){
|
||||||
|
startingAnimationIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
|
||||||
|
isStarted = true;
|
||||||
|
for(int i = 0 ; i < players.size() ; i++){
|
||||||
|
players.get(i).update();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0 ; i < missiles.size() ; i++){
|
||||||
|
missiles.get(i).update();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0 ; i < enemies.size() ; i++){
|
||||||
|
enemies.get(i).update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void movePlayers() {
|
||||||
|
/**
|
||||||
|
* Player 1 Movement:
|
||||||
|
*/
|
||||||
|
if(keys.get(engine.getP1Controlles()[GameEngine.UP]) ){ //UP
|
||||||
|
players.get(0).sethDirection(1);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP1Controlles()[GameEngine.DOWN])){ // DOWN
|
||||||
|
players.get(0).sethDirection(-1);
|
||||||
|
}
|
||||||
|
if(!keys.get(engine.getP1Controlles()[GameEngine.UP]) && !keys.get(engine.getP1Controlles()[GameEngine.DOWN])){ // Not up Or Down
|
||||||
|
players.get(0).sethDirection(0);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP1Controlles()[GameEngine.LEFT])) { // Left
|
||||||
|
players.get(0).setvDirection(-1);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP1Controlles()[GameEngine.RIGHT])) { // Right
|
||||||
|
players.get(0).setvDirection(1);
|
||||||
|
}
|
||||||
|
if(!keys.get(engine.getP1Controlles()[GameEngine.LEFT]) && !keys.get(engine.getP1Controlles()[GameEngine.RIGHT])){ // Not right or left
|
||||||
|
players.get(0).setvDirection(0);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP1Controlles()[GameEngine.FIRE]) ){
|
||||||
|
if(players.get(0).isAbleToFire()){
|
||||||
|
missiles.add(new Missile(players.get(0).getCenterX() - 3, (int)players.get(0).getLocY(), players.get(0).getAcceleration() + 3, "P1Laser.png"));
|
||||||
|
players.get(0).updateFireTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player 2 Movement
|
||||||
|
*/
|
||||||
|
if(numOfPlayers > 1){
|
||||||
|
if(keys.get(engine.getP2Controlles()[GameEngine.UP]) ){ //UP
|
||||||
|
players.get(1).sethDirection(1);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP2Controlles()[GameEngine.DOWN])){ // DOWN
|
||||||
|
players.get(1).sethDirection(-1);
|
||||||
|
}
|
||||||
|
if(!keys.get(engine.getP2Controlles()[GameEngine.UP]) && !keys.get(engine.getP2Controlles()[GameEngine.DOWN])){ // Not up Or Down
|
||||||
|
players.get(1).sethDirection(0);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP2Controlles()[GameEngine.LEFT])) { // Left
|
||||||
|
players.get(1).setvDirection(-1);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP2Controlles()[GameEngine.RIGHT])) { // Right
|
||||||
|
players.get(1).setvDirection(1);
|
||||||
|
}
|
||||||
|
if(!keys.get(engine.getP2Controlles()[GameEngine.LEFT]) && !keys.get(engine.getP2Controlles()[GameEngine.RIGHT])){ // Not right or left
|
||||||
|
players.get(1).setvDirection(0);
|
||||||
|
}
|
||||||
|
if(keys.get(engine.getP2Controlles()[GameEngine.FIRE]) ){
|
||||||
|
if(players.get(1).isAbleToFire()){
|
||||||
|
missiles.add(new Missile(players.get(1).getCenterX() - 3, (int)players.get(1).getLocY(), players.get(1).getAcceleration() + 3, "P1Laser.png"));
|
||||||
|
players.get(1).updateFireTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(JPanel p) {
|
||||||
|
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
||||||
|
Graphics g = sceneImage.getGraphics();
|
||||||
|
|
||||||
|
bg.drawSprite(g, p);
|
||||||
|
Color c = g.getColor();
|
||||||
|
if(!isStarted){
|
||||||
|
Font f = engine.getGameFont();
|
||||||
|
if(f == null) {
|
||||||
|
f = g.getFont();
|
||||||
|
}
|
||||||
|
f = f.deriveFont(60F);
|
||||||
|
g.setColor(Color.DARK_GRAY);
|
||||||
|
g.setFont(f);
|
||||||
|
|
||||||
|
|
||||||
|
// Get the FontMetrics
|
||||||
|
FontMetrics metrics = g.getFontMetrics(f);
|
||||||
|
// Determine the X coordinate for the text
|
||||||
|
int x = (stageWidth - metrics.stringWidth(this.title)) / 2;
|
||||||
|
// Determine the Y coordinate for the text
|
||||||
|
int y = ((stageHeight - metrics.getHeight()) / 2) - metrics.getAscent();
|
||||||
|
g.drawString(this.title, x, y);
|
||||||
|
g.setColor(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for(int i = 0 ; i < missiles.size() ; i++){
|
||||||
|
missiles.get(i).drawSprite(g,p);
|
||||||
|
}
|
||||||
|
for(int i = 0 ; i < players.size() ; i++){
|
||||||
|
players.get(i).drawSprite(g,p);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0 ; i < enemies.size() ; i++){
|
||||||
|
enemies.get(i).drawSprite(g,p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent keyEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent keyEvent) {
|
||||||
|
if(isStarted)
|
||||||
|
keys.put(keyEvent.getKeyCode(), true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent keyEvent) {
|
||||||
|
if(isStarted)
|
||||||
|
keys.put(keyEvent.getKeyCode(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class fireTimer implements ActionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
missiles.add(new Missile(((EnemyShip)actionEvent.getSource()).getCenterX(), (int)((EnemyShip)actionEvent.getSource()).getLocY(), ((EnemyShip)actionEvent.getSource()).getAcceleration() + 3, "P1Laser.png"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class enemyWaveLaunch implements ActionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class enemyLaunch implements ActionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
enemies.add(new EnemyShip(0,0,0,0,3,"L1-ES1.png",0,15,15,new fireTimer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
101
src/com/sagi/dayan/Games/Stage/MainMenuScene.java
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package com.sagi.dayan.Games.Stage;
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Elements.MenuBoxSprite;
|
||||||
|
import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
import sun.audio.AudioPlayer;
|
||||||
|
import sun.audio.AudioStream;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/24/16.
|
||||||
|
*/
|
||||||
|
public class MainMenuScene extends Scene {
|
||||||
|
|
||||||
|
private MenuBoxSprite menuBox;
|
||||||
|
private int menuItem;
|
||||||
|
|
||||||
|
|
||||||
|
private final int MAX_ITEM_INDEX = 3, X_AXIS=560, ITEM_EXIT = 3, ITEM_SETTINGS = 2, ITEM_2P = 1, ITEM_1P = 0;
|
||||||
|
private int[] axis = {370, 480, 590, 700};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public MainMenuScene(int stageWidth, int stageHeight, GameEngine engine) {
|
||||||
|
super(stageWidth, stageHeight, engine);
|
||||||
|
menuItem = 0;
|
||||||
|
menuBox = new MenuBoxSprite(X_AXIS, axis[menuItem], stageWidth, stageHeight, 0, "menu.jpg", 0, 425, 110); //bImage is the background... not trivial
|
||||||
|
try {
|
||||||
|
AudioPlayer.player.start(new AudioStream(Utils.getSoundResourceAsStream("intro.wav")));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
menuBox.setLocY(axis[menuItem]);
|
||||||
|
menuBox.update();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(JPanel p) {
|
||||||
|
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
||||||
|
Graphics g = sceneImage.getGraphics();
|
||||||
|
g.drawImage(menuBox.getbImage(), 0, 0, p);
|
||||||
|
menuBox.drawSprite(g, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent keyEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent keyEvent) {
|
||||||
|
switch (keyEvent.getKeyCode()){
|
||||||
|
case KeyEvent.VK_UP:
|
||||||
|
if(menuItem == 0)
|
||||||
|
menuItem = MAX_ITEM_INDEX;
|
||||||
|
else
|
||||||
|
menuItem--;
|
||||||
|
Utils.playSound("menuSelect.wav");
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_DOWN:
|
||||||
|
if(menuItem == MAX_ITEM_INDEX)
|
||||||
|
menuItem = 0;
|
||||||
|
else
|
||||||
|
menuItem++;
|
||||||
|
Utils.playSound("menuSelect.wav");
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_ENTER:
|
||||||
|
switch(menuItem){
|
||||||
|
case ITEM_1P:
|
||||||
|
case ITEM_2P:
|
||||||
|
Utils.playSound("menuItem.wav");
|
||||||
|
engine.startGame(menuItem+1);
|
||||||
|
break;
|
||||||
|
case ITEM_SETTINGS:
|
||||||
|
Utils.playSound("menuItem.wav");
|
||||||
|
engine.goToSettings();
|
||||||
|
break;
|
||||||
|
case ITEM_EXIT:
|
||||||
|
System.exit(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent keyEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
118
src/com/sagi/dayan/Games/Stage/SampleScene.java
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package com.sagi.dayan.Games.Stage;
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Elements.*;
|
||||||
|
import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/10/16.
|
||||||
|
*/
|
||||||
|
public class SampleScene extends Scene {
|
||||||
|
private final int STOP=0, UP=1, DOWN=-1, TURN_SPEED=10;
|
||||||
|
private DemoSprite sprite;
|
||||||
|
private AnimatedDemoSprite animated;
|
||||||
|
private int r = 0, g = 0, b = 0;
|
||||||
|
private boolean toWhite = true;
|
||||||
|
|
||||||
|
public SampleScene(int width, int height, GameEngine engine){
|
||||||
|
super(width, height, engine);
|
||||||
|
// sprite = new DemoSprite(50,50,width, height, 50);
|
||||||
|
animated = new AnimatedDemoSprite(width/2, height/2, width, height,5,"animatedSample.png", 0, 58,87);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
sprite.update();
|
||||||
|
animated.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(JPanel p) {
|
||||||
|
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
||||||
|
Graphics g = sceneImage.getGraphics();
|
||||||
|
g.setColor(getColor());
|
||||||
|
g.fillRect(0,0,stageWidth, stageWidth);
|
||||||
|
sprite.drawSprite(g, p);
|
||||||
|
animated.drawSprite(g, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent keyEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent keyEvent) {
|
||||||
|
System.out.println("Pressed!");
|
||||||
|
|
||||||
|
if (keyEvent.getKeyCode() == keyEvent.VK_LEFT) {
|
||||||
|
sprite.turnShip(DOWN);
|
||||||
|
}
|
||||||
|
if (keyEvent.getKeyCode() == keyEvent.VK_RIGHT) {
|
||||||
|
sprite.turnShip(UP);
|
||||||
|
}
|
||||||
|
if (keyEvent.getKeyCode() == keyEvent.VK_UP) {
|
||||||
|
sprite.setDirection(UP);
|
||||||
|
}
|
||||||
|
if (keyEvent.getKeyCode() == keyEvent.VK_DOWN) {
|
||||||
|
sprite.setDirection(DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent keyEvent) {
|
||||||
|
switch (keyEvent.getKeyCode()){
|
||||||
|
case KeyEvent.VK_UP:
|
||||||
|
case KeyEvent.VK_DOWN:
|
||||||
|
sprite.setDirection(STOP);
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_RIGHT:
|
||||||
|
case KeyEvent.VK_LEFT:
|
||||||
|
sprite.turnShip(STOP);
|
||||||
|
break;
|
||||||
|
// case KeyEvent.VK_SPACE:
|
||||||
|
// laserAudioClip.stop();
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mousePressed(MouseEvent e){
|
||||||
|
System.out.println("Mouse pressed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color getColor() {
|
||||||
|
if(toWhite){
|
||||||
|
if(r < 225) {
|
||||||
|
r++;
|
||||||
|
} else if (g < 225) {
|
||||||
|
g++;
|
||||||
|
} else if ( b < 225) {
|
||||||
|
b++;
|
||||||
|
}else if (r == 225 && g ==225 && b == 225){
|
||||||
|
toWhite = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(b > 0) {
|
||||||
|
b--;
|
||||||
|
} else if (g > 0) {
|
||||||
|
g--;
|
||||||
|
} else if ( r > 0) {
|
||||||
|
r--;
|
||||||
|
}else if (r == 0 && g ==0 && b == 0){
|
||||||
|
toWhite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Color(r, g, b);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
36
src/com/sagi/dayan/Games/Stage/Scene.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package com.sagi.dayan.Games.Stage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/8/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Elements.*;
|
||||||
|
import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
public abstract class Scene extends MouseAdapter implements KeyListener{
|
||||||
|
|
||||||
|
protected int stageWidth, stageHeight;
|
||||||
|
protected BufferedImage sceneImage;
|
||||||
|
protected GameEngine engine;
|
||||||
|
|
||||||
|
public Scene (int stageWidth, int stageHeight, GameEngine engine) {
|
||||||
|
this.stageWidth = stageWidth;
|
||||||
|
this.stageHeight = stageHeight;
|
||||||
|
this.engine = engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void update ();
|
||||||
|
|
||||||
|
public abstract void render(JPanel p);
|
||||||
|
|
||||||
|
public BufferedImage getSceneImage () {
|
||||||
|
return sceneImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
src/com/sagi/dayan/Games/Stage/SettingsMenuScene.java
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package com.sagi.dayan.Games.Stage;
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
import sun.audio.AudioPlayer;
|
||||||
|
import sun.audio.AudioStream;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/27/16.
|
||||||
|
*/
|
||||||
|
public class SettingsMenuScene extends Scene {
|
||||||
|
private BufferedImage background;
|
||||||
|
|
||||||
|
|
||||||
|
public SettingsMenuScene(int stageWidth, int stageHeight, GameEngine engine) {
|
||||||
|
super(stageWidth, stageHeight, engine);
|
||||||
|
try {
|
||||||
|
background = ImageIO.read(Utils.getImageResourceAsURL("Settigns_menu.jpg"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(JPanel p) {
|
||||||
|
sceneImage = new BufferedImage(this.stageWidth, this.stageHeight, Image.SCALE_FAST);
|
||||||
|
Graphics g = sceneImage.getGraphics();
|
||||||
|
g.drawImage(background, 0,0,p);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent keyEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent keyEvent) {
|
||||||
|
switch (keyEvent.getKeyCode()){
|
||||||
|
case KeyEvent.VK_ESCAPE:
|
||||||
|
Utils.playSound("menuItem.wav");
|
||||||
|
engine.goToMainMenu();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent keyEvent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
109
src/com/sagi/dayan/Games/Stage/Stage.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package com.sagi.dayan.Games.Stage;
|
||||||
|
|
||||||
|
import com.sagi.dayan.Games.Engine.GameEngine;
|
||||||
|
import com.sagi.dayan.Games.Utils.Utils;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferStrategy;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/8/16.
|
||||||
|
*/
|
||||||
|
public class Stage extends JPanel implements Runnable{
|
||||||
|
|
||||||
|
private Vector<Scene> scenes;
|
||||||
|
private int currentScene;
|
||||||
|
private int fWidth, fHeight;
|
||||||
|
private long startTime;
|
||||||
|
private GameEngine engine;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Stage(int width, int height) {
|
||||||
|
this.setDoubleBuffered(true);
|
||||||
|
this.fHeight = height;
|
||||||
|
this.setSize(width, height);
|
||||||
|
this.setVisible(true);
|
||||||
|
this.scenes = new Vector<>();
|
||||||
|
this.engine = new GameEngine(width, height, this);
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
currentScene = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.setFocusable(true);
|
||||||
|
this.requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void update() {
|
||||||
|
engine.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void render() {
|
||||||
|
engine.render(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
// System.out.println("Paint Component");
|
||||||
|
super.paintComponent(g);
|
||||||
|
g.drawImage(engine.getScene(),0,0,this);
|
||||||
|
g.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
double nsPerTick = 1000000000D / 60D; // ( 1 Billion / 60)
|
||||||
|
long lastTimer = System.currentTimeMillis();
|
||||||
|
boolean toRender = false;
|
||||||
|
long lastTime = System.nanoTime();
|
||||||
|
int ticks = 0;
|
||||||
|
int frames = 0;
|
||||||
|
double delta = 0;
|
||||||
|
|
||||||
|
while(engine.gameOn){
|
||||||
|
|
||||||
|
long now = System.nanoTime();
|
||||||
|
delta += (now - lastTime) / nsPerTick;
|
||||||
|
lastTime = now;
|
||||||
|
|
||||||
|
if (delta >= 1) {
|
||||||
|
update();
|
||||||
|
ticks++;
|
||||||
|
delta -= 1;
|
||||||
|
toRender = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toRender) { // render
|
||||||
|
frames++;
|
||||||
|
render();
|
||||||
|
toRender = false;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(20);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (System.currentTimeMillis() - lastTimer > 1000) {
|
||||||
|
lastTimer += 1000;
|
||||||
|
System.out.println("Ticks: " + ticks + "\tFps: " + frames + "\tScenes Size: " + engine.getScenesSize());
|
||||||
|
frames = 0;
|
||||||
|
ticks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotify(){
|
||||||
|
super.addNotify();
|
||||||
|
(new Thread(this)).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
src/com/sagi/dayan/Games/Utils/Utils.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package com.sagi.dayan.Games.Utils;
|
||||||
|
|
||||||
|
import sun.audio.AudioPlayer;
|
||||||
|
import sun.audio.AudioStream;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sagi on 2/24/16.
|
||||||
|
*/
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
public static InputStream getSoundResourceAsStream(String soundFileName){
|
||||||
|
return Utils.class.getResourceAsStream("/com/sagi/dayan/Games/Sounds/" + soundFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static URL getSoundResourceAsURL(String soundFileName){
|
||||||
|
return Utils.class.getResource("/com/sagi/dayan/Games/Sounds/" + soundFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream getImageResourceAsStream(String soundFileName){
|
||||||
|
return Utils.class.getResourceAsStream("/com/sagi/dayan/Games/Images/" + soundFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static URL getImageResourceAsURL(String soundFileName){
|
||||||
|
return Utils.class.getResource("/com/sagi/dayan/Games/Images/" + soundFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void playSound(String soundFileName){
|
||||||
|
try {
|
||||||
|
AudioPlayer.player.start(new AudioStream(Utils.getSoundResourceAsStream(soundFileName)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFontPath(String fontFileName) {
|
||||||
|
return Utils.class.getResource("/com/sagi/dayan/Games/Fonts/" + fontFileName).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream getFontStream(String fontFileName) {
|
||||||
|
return Utils.class.getResourceAsStream("/com/sagi/dayan/Games/Fonts/" + fontFileName);
|
||||||
|
}
|
||||||
|
}
|