246 lines
8.2 KiB
Java
246 lines
8.2 KiB
Java
package de.miaurizius.jgame2d.core;
|
|
|
|
import de.miaurizius.jgame2d.core.enums.GameState;
|
|
import de.miaurizius.jgame2d.core.handlers.*;
|
|
import de.miaurizius.jgame2d.entity.Entity;
|
|
import de.miaurizius.jgame2d.entity.Player;
|
|
import de.miaurizius.jgame2d.tile.TileManager;
|
|
import de.miaurizius.jgame2d.tile.interactive.InteractiveTile;
|
|
|
|
import javax.sound.sampled.Clip;
|
|
import javax.sound.sampled.FloatControl;
|
|
import javax.swing.*;
|
|
import java.awt.*;
|
|
import java.awt.image.BufferedImage;
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.logging.Level;
|
|
|
|
public class GamePanel extends JPanel implements Runnable {
|
|
|
|
// SCREEN SETTINGS
|
|
final int originalTileSize = 16; //16x16 tile
|
|
final int scale = 3;
|
|
public final int tileSize = originalTileSize * scale; //48x48 tile
|
|
public final int maxScreenCol = 20;
|
|
public final int maxScreenRow = 12;
|
|
public final int screenWidth = tileSize * maxScreenCol; // 960 pixels
|
|
public final int screenHeight = tileSize * maxScreenRow; // 576 pixels
|
|
|
|
// FULLSCREEN SETTINGS
|
|
public boolean fullscreen;
|
|
int fScreenWidth = screenWidth;
|
|
int fScreenHeight = screenHeight;
|
|
BufferedImage tempScreen;
|
|
Graphics2D fg2;
|
|
|
|
// WORLD SETTINGS
|
|
public final int maxWorldCol = 50;
|
|
public final int maxWorldRow = 50;
|
|
public final String currentMap = "testmap2";
|
|
|
|
//FPS
|
|
final int FPS = 60;
|
|
int fpsMeasure;
|
|
|
|
// SYSTEM
|
|
public TileManager tileM = new TileManager(this);
|
|
public KeyHandler keyH = new KeyHandler(this);
|
|
public CollisionHandler collisionH = new CollisionHandler(this);
|
|
public AssetSetter assetSetter = new AssetSetter(this);
|
|
public UI ui = new UI(this);
|
|
public EventHandler eventH = new EventHandler(this);
|
|
public Sound sfx = new Sound();
|
|
public Sound music = new Sound();
|
|
public Config config = new Config(this);
|
|
Thread gameThread;
|
|
|
|
// ENTITY AND OBJECT
|
|
public Player player = new Player(this, keyH);
|
|
public Entity[] obj = new Entity[20];
|
|
public Entity[] npc = new Entity[10];
|
|
public Entity[] monster = new Entity[20];
|
|
public InteractiveTile[] iTile = new InteractiveTile[50];
|
|
public ArrayList<Entity> projectileList = new ArrayList<>();
|
|
public ArrayList<Entity> particleList = new ArrayList<>();
|
|
ArrayList<Entity> entityList = new ArrayList<>();
|
|
|
|
// GAME STATE
|
|
public GameState gameState;
|
|
|
|
public GamePanel() {
|
|
this.setPreferredSize(new Dimension(screenWidth, screenHeight));
|
|
this.setBackground(Color.black);
|
|
this.setDoubleBuffered(true);
|
|
this.addKeyListener(keyH);
|
|
this.setFocusable(true);
|
|
}
|
|
|
|
// GAME THREAD / CORE
|
|
public void startGameThread() {
|
|
gameThread = new Thread(this);
|
|
gameThread.start();
|
|
}
|
|
@Override
|
|
public void run() {
|
|
double drawInterval = (double) 1000000000 / FPS;
|
|
double delta = 0;
|
|
double lastTime = System.nanoTime();
|
|
long currentTime;
|
|
long timer = 0;
|
|
int drawCount = 0;
|
|
|
|
while(gameThread != null) {
|
|
currentTime = System.nanoTime();
|
|
delta += (currentTime - lastTime) / drawInterval;
|
|
timer += (long) (currentTime - lastTime);
|
|
lastTime = currentTime;
|
|
|
|
if(delta >= 1) {
|
|
update();
|
|
//repaint(); //since the new drawing method
|
|
drawTempScreen();
|
|
drawScreen();
|
|
delta--;
|
|
drawCount++;
|
|
}
|
|
if(timer >= 1000000000) {
|
|
fpsMeasure = drawCount;
|
|
drawCount = 0;
|
|
timer = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// FRAME GENERATION
|
|
public void update() {
|
|
switch(gameState) {
|
|
case PLAY:
|
|
player.update();
|
|
for(Entity entity : npc) if(entity != null) entity.update();
|
|
for(int i = 0; i < monster.length; i++) {
|
|
Entity m = monster[i];
|
|
if(m != null) {
|
|
if(m.alive && !m.dying) m.update();
|
|
if(!m.alive) {
|
|
monster[i].checkDrop();
|
|
monster[i] = null;
|
|
}
|
|
}
|
|
}
|
|
for(int i = 0; i < projectileList.size(); i++) {
|
|
Entity m = projectileList.get(i);
|
|
if(m != null) {
|
|
if(m.alive) m.update();
|
|
else projectileList.remove(i);
|
|
}
|
|
}
|
|
for(int i = 0; i < particleList.size(); i++) {
|
|
Entity m = particleList.get(i);
|
|
if(m != null) {
|
|
if(m.alive) m.update();
|
|
else particleList.remove(i);
|
|
}
|
|
}
|
|
for(Entity entity : iTile) if(entity != null) entity.update();
|
|
break;
|
|
case PAUSE:
|
|
break;
|
|
}
|
|
}
|
|
public void drawTempScreen() {
|
|
// DEBUG
|
|
long drawStart;
|
|
drawStart = System.nanoTime();
|
|
|
|
// TITLE SCREEN
|
|
if(gameState == GameState.TITLE) {
|
|
ui.draw(fg2);
|
|
return;
|
|
}
|
|
|
|
// GAME
|
|
tileM.draw(fg2);
|
|
for(Entity entity : iTile) if(entity != null) entity.draw(fg2);
|
|
|
|
// ENTITY RENDER SYSTEM
|
|
entityList.add(player);
|
|
for(Entity entity : npc) if(entity != null) entityList.add(entity);
|
|
for(Entity entity : obj) if(entity != null) entityList.add(entity);
|
|
for(Entity entity : monster) if(entity != null) entityList.add(entity);
|
|
for(Entity entity : projectileList) if(entity != null) entityList.add(entity);
|
|
for(Entity entity : particleList) if(entity != null) entityList.add(entity);
|
|
entityList.sort(Comparator.comparingInt(o -> o.worldY));
|
|
for(Entity entity : entityList) entity.draw(fg2);
|
|
entityList.clear();
|
|
|
|
ui.draw(fg2);
|
|
|
|
long drawEnd = System.nanoTime();
|
|
long passed = drawEnd - drawStart;
|
|
|
|
// DEBUG
|
|
if(keyH.debug) {
|
|
int start = 350;
|
|
fg2.setColor(Color.white);
|
|
fg2.drawString("Draw Time: " + passed, 10, start);
|
|
fg2.drawString("FPS: " + fpsMeasure, 10, start+tileSize);
|
|
fg2.drawString("Invincible: " + player.invincibleCount, 10, start+tileSize*2);
|
|
fg2.drawString("X, Y: " + player.worldX+", "+player.worldY, 10, start+tileSize*3);
|
|
fg2.drawString("Col, Row: " + (player.worldX+player.solidArea.x)/tileSize+", "+(player.worldY+player.solidArea.y)/tileSize, 10, start+tileSize*4);
|
|
Boot.logger.log(Level.FINE, "Draw Time: " + passed);
|
|
}
|
|
}
|
|
public void drawScreen() {
|
|
Graphics fg = getGraphics();
|
|
fg.drawImage(tempScreen, 0, 0, fScreenWidth, fScreenHeight, null);
|
|
fg.dispose();
|
|
}
|
|
|
|
// MUSIC
|
|
public void playMusic(int i) {
|
|
Clip c = music.clips[i];
|
|
music.clip = c;
|
|
music.fc = (FloatControl) c.getControl(FloatControl.Type.MASTER_GAIN);
|
|
music.checkVolume();
|
|
if(c.isRunning()) c.stop();
|
|
c.setFramePosition(0);
|
|
c.start();
|
|
c.loop(Clip.LOOP_CONTINUOUSLY);
|
|
}
|
|
public void stopMusic() {
|
|
music.stop();
|
|
}
|
|
public void playSE(int i) {
|
|
Clip c = sfx.clips[i];
|
|
sfx.fc = (FloatControl) c.getControl(FloatControl.Type.MASTER_GAIN);
|
|
sfx.checkVolume();
|
|
if(c.isRunning()) c.stop();
|
|
c.setFramePosition(0);
|
|
c.start();
|
|
}
|
|
|
|
// SETTING THINGS UP
|
|
public void setupGame() {
|
|
assetSetter.setObject();
|
|
assetSetter.setNPC();
|
|
assetSetter.setMonster();
|
|
assetSetter.setITiles();
|
|
gameState = GameState.TITLE;
|
|
|
|
tempScreen = new BufferedImage(screenWidth, screenHeight, BufferedImage.TYPE_INT_RGB);
|
|
fg2 = (Graphics2D) tempScreen.getGraphics();
|
|
|
|
if(fullscreen) setFullscreen();
|
|
}
|
|
public void setFullscreen() {
|
|
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
|
GraphicsDevice gd = ge.getDefaultScreenDevice();
|
|
gd.setFullScreenWindow(Boot.window);
|
|
|
|
fScreenWidth = Boot.window.getWidth();
|
|
fScreenHeight = Boot.window.getHeight();
|
|
}
|
|
|
|
}
|