Hallo Leute, :meld:
ich habe dieses Thema eröffnet, um hier mit euch ein kleines Projekt voranzutreiben 8 :hihi:
Das "Projekt Library" :toll: Ja, ich weiß, dass der Name beschissen ist :bahnhof:
Darum geht's 8 Im Rahmen des Java-Forum's möchte ich mit euch eine etwas komplexere 2D-Spiele-Bibliothek erstellen, :idea:
beziehungsweise erweitern, denn ich habe in diese Richtung bereits selbst etwas vorangearbeitet; und nun möchte ich es mit eurer Hilfe ausbauen
Hier ein paar Klassen 8 :rtfm:
[TIPP]
Inspiriert dazu wurde ich durch Quaxli's Spiele-Tutorial
[/TIPP]
Im Anhang befindet sich außerdem der zugehörige Eclipse-workspace opcorn:
ich habe dieses Thema eröffnet, um hier mit euch ein kleines Projekt voranzutreiben 8 :hihi:
Das "Projekt Library" :toll: Ja, ich weiß, dass der Name beschissen ist :bahnhof:
Darum geht's 8 Im Rahmen des Java-Forum's möchte ich mit euch eine etwas komplexere 2D-Spiele-Bibliothek erstellen, :idea:
beziehungsweise erweitern, denn ich habe in diese Richtung bereits selbst etwas vorangearbeitet; und nun möchte ich es mit eurer Hilfe ausbauen
Hier ein paar Klassen 8 :rtfm:
Java:
package de.androbin.lib.games;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.sun.xml.internal.ws.api.ResourceLoader;
public class AnimationLib {
protected HashMap<String, ArrayList<BufferedImage>> animations;
public void addAnimation( String name, ArrayList<BufferedImage> animation ) { animations.put( name, animation ); }
public void loadAnimation( String name, String path ) {
if ( animations.containsKey( name ) ) return;
ArrayList<BufferedImage> animation = new ArrayList<BufferedImage>();
for ( int i = 0; new File( path + i + ".png" ).exists(); i++ ) {
try { animation.add( ImageIO.read( ResourceLoader.class.getResource( path + i + ".png" ) ) ); }
catch ( IOException e ) { break; }
}
animations.put( name, animation );
}
public ArrayList<BufferedImage> getAnimation( String name ) { return animations.get( name ); }
}
Java:
package de.androbin.lib.games;
public enum Direction { Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight; }
Java:
package de.androbin.lib.games;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.HashMap;
public interface Drawable {
// Deklarationen
int x = 0, y = 0, width = 0, height = 0;
HashMap<Integer, BufferedImage> tiles = new HashMap<Integer, BufferedImage>();
int pic = 0;
boolean remove = false;
// Methoden
public void paintComponent( Graphics g );
}
Java:
package de.androbin.lib.games;
public class Mob extends Player {
// Deklarationen
private static final long serialVersionUID = 1L;
// Methoden
protected static Direction randomDir() { return Direction.values()[ (int) ( Math.random() * 4 ) ]; }
}
Java:
package de.androbin.lib.games;
public interface Movable {
// Deklarationen
double x = 0, y = 0, width = 0, height = 0;
boolean remove = false;
// Methoden
public boolean checkCollision( Sprite s );
public void moveTo( Direction dir );
public void moveTo( double x, double y );
}
Java:
package de.androbin.lib.games;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.sun.xml.internal.ws.api.ResourceLoader;
public class Player extends Sprite {
// Deklarationen
private static final long serialVersionUID = 1L;
protected HashMap<String, BufferedImage> tiles = new HashMap<String, BufferedImage>();
protected String name = "";
protected Direction dir = Direction.Down;
// Konstruktoren
public Player() { }
public Player( String name, String url, Direction dir, double x, double y, double width, double height ) {
this.name = name; this.dir = dir; this.x = x; this.y = y; this.width = width; this.height = height;
for ( int i = 0; i < Direction.values().length; i++ ) {
for ( int j = 0; j != -1; j++ ) {
try { tiles.put( dirToString( Direction.values()[ i ] ) + j,
ImageIO.read( ResourceLoader.class.getResource( url + dirToString( Direction.values()[ i ] ) + j + ".png" ) ) ); }
catch ( Exception e ) { j = -1; }
}
}
}
// Methoden
public String dirToString() { return dirToString( dir ); }
public static String dirToString( Direction dir ) {
switch ( dir ) {
default : return "";
case Up : return "U";
case Down : return "D";
case Left : return "L";
case Right : return "R";
case UpLeft : return "UL";
case UpRight : return "UR";
case DownLeft : return "DL";
case DownRight : return "DR";
}
}
public void turn( Direction dir ) { this.dir = dir; }
@Override
public boolean checkCollision( Sprite s ) {
Rectangle2D.Double cut = (Double) this.createIntersection( s );
if ( ( cut.width < 1 ) || ( cut.height < 1 ) ) return false;
Rectangle2D.Double sub_me = getSubRec( this, cut );
Rectangle2D.Double sub_him = getSubRec( s , cut );
BufferedImage img_me = tiles.get( dirToString() + pic ).getSubimage( (int) sub_me .x, (int) sub_me .y, (int) sub_me .width, (int) sub_me .height );
BufferedImage img_him = s.tiles.get( s.pic ).getSubimage( (int) sub_him.x, (int) sub_him.y, (int) sub_him.width, (int) sub_him.height );
for ( int x = 0; x < img_me.getWidth(); x++ ) {
for ( int y = 0; y < img_him.getHeight(); y++ ) {
int rgb1 = img_me .getRGB( x, y );
int rgb2 = img_him.getRGB( x, y );
if ( isOpaque( rgb1 ) && isOpaque( rgb2 ) ) { return true; }
}
}
return false;
}
@ Override
public void moveTo( Direction dir ) { super.moveTo( dir ); this.dir = dir; }
@ Override
public void moveTo( double x, double y ) { super.moveTo( x, y ); dir = Direction.Down; }
public void moveTo( Direction dir, int x, int y ) { super.moveTo( x, y ); this.dir = dir; }
@Override
public void paintComponent( Graphics g ) {
Graphics2D g2 = (Graphics2D) g;
if ( pic >= tiles.size() / Direction.values().length ) pic = 0;
g2.drawImage( tiles.get( dirToString() + pic++ ), (int) x, (int) y, (int) width, (int) height, null );
if ( animpic == -1 || playAnimation ) {
if ( animpic == -1 ) { animpic = 0; playAnimation = true; }
if ( animpic >= animation.size() ) { animpic = 0; playAnimation = false; animation.clear(); return; }
g2.drawImage( animation.get( animpic++ ), (int) x, (int) y, (int) width, (int) height, null );
}
g2.setColor( Color.WHITE );
g2.setFont( new Font( "TimesRoman", Font.PLAIN, 20 ) );
g2.drawString( name, (int) x, (int) y - 20 );
}
}
Java:
package de.androbin.lib.games;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;
import java.util.Hashtable;
import java.util.Vector;
public class SoundLib {
Hashtable<String, AudioClip> sounds = new Hashtable<String, AudioClip>();
Vector <AudioClip> loopingClips = new Vector <AudioClip>();
public void loadSound( String name, String path ) {
if ( sounds.containsKey( name ) ) return;
URL sound_url = getClass().getClassLoader().getResource( path );
sounds.put( name, Applet.newAudioClip( sound_url ) );
}
public void playSound( String name ) { sounds.get( name ).play(); }
public void loopSound( String name ) {
AudioClip audio = sounds.get( name );
loopingClips.add( audio );
audio.loop();
}
public void stopLoopingSounds() { for ( AudioClip c : loopingClips ) c.stop(); }
}
Java:
package de.androbin.lib.games;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.sun.xml.internal.ws.api.ResourceLoader;
public class Sprite extends Rectangle2D.Double implements Drawable, Movable {
// Deklarationen
private static final long serialVersionUID = 1L;
protected double x = 0, y = 0, width = 0, height = 0;
protected HashMap <Integer, BufferedImage> tiles = new HashMap <Integer, BufferedImage>();
protected ArrayList< BufferedImage> animation = new ArrayList< BufferedImage>();
protected int pic = 0, animpic = 0;
protected AnimationLib animationlib = new AnimationLib();
protected SoundLib soundlib = new SoundLib ();
protected boolean playAnimation = false;
protected boolean remove = false;
// Konstruktoren
public Sprite() { }
public Sprite( String url, double x, double y, double width, double height ) {
this.x = x; this.y = y; this.width = width; this.height = height;
for ( int i = 0; i != -1; i++ ) { try { tiles.put( i, ImageIO.read( ResourceLoader.class.getResource( url + i + ".png" ) ) ); } catch ( Exception e ) { i = -1; } }
}
public Sprite( HashMap<Integer, BufferedImage> tiles, double x, double y, double width, double height ) { this.tiles = tiles; this.x = x; this.y = y; this.width= width; this.height = height; }
public Sprite( ArrayList<BufferedImage> animation, double x, double y, double width, double height ) { this.animation = animation; this.x = x; this.y = y; this.width = width; this.height = height; }
public Sprite( String url, Sprite parent ) { this( url, parent.x, parent.y, parent.width, parent.height ); }
// Methoden
@ Override
public void paintComponent( Graphics g ) {
Graphics2D g2 = (Graphics2D) g;
if ( pic >= tiles.size() ) pic = 0;
g2.drawImage( tiles.get( pic++ ), (int) x, (int) y, (int) width, (int) height, null );
if ( animpic == -1 || playAnimation ) {
if ( animpic == -1 ) { animpic = 0; playAnimation = true; }
if ( animpic >= animation.size() ) { animpic = 0; playAnimation = false; animation.clear(); return; }
g2.drawImage( animation.get( animpic++ ), (int) x, (int) y, (int) width, (int) height, null );
}
}
public static Rectangle2D.Double getSubRec( Rectangle2D.Double source, Rectangle2D.Double part ) {
Rectangle2D.Double sub = new Rectangle2D.Double();
if ( source.x > part.x ) sub.x = 0;
else sub.x = part.x - source.x;
if( source.y > part.y ) sub.y = 0;
else sub.y = part.y - source.y;
sub.width = part.width;
sub.height = part.height;
return sub;
}
public static boolean isOpaque( int rgb ) { return !( ( ( rgb >> 24 ) & 0xff ) == 0 ); }
@Override
public boolean checkCollision( Sprite s ) {
Rectangle2D.Double cut = (Double) this.createIntersection( s );
if ( ( cut.width < 1 ) || ( cut.height < 1 ) ) return false;
Rectangle2D.Double sub_me = getSubRec( this, cut );
Rectangle2D.Double sub_him = getSubRec( s , cut );
BufferedImage img_me = tiles.get( pic ).getSubimage( (int) sub_me .x, (int) sub_me .y, (int) sub_me .width, (int) sub_me .height );
BufferedImage img_him = s.tiles.get( s.pic ).getSubimage( (int) sub_him.x, (int) sub_him.y, (int) sub_him.width, (int) sub_him.height );
for ( int x = 0; x < img_me.getWidth(); x++ ) {
for ( int y = 0; y < img_him.getHeight(); y++ ) {
int rgb1 = img_me .getRGB( x, y );
int rgb2 = img_him.getRGB( x, y );
if ( isOpaque( rgb1 ) && isOpaque( rgb2 ) ) { return true; }
}
}
return false;
}
@ Override
public void moveTo( Direction dir ) {
switch ( dir ) {
default : return;
case Up : y--; return;
case Down : y++; return;
case Left : x--; return;
case Right : x++; return;
case UpLeft : x--; y--; return;
case UpRight : x++; y--; return;
case DownLeft : x--; y++; return;
case DownRight : x++; y++; return;
}
}
@ Override
public void moveTo( double x, double y ) { this.x = x; this.y = y; }
protected void playAnimation( ArrayList<BufferedImage> animation ) { this.animation = animation; animpic = -1;; }
protected void loadSound( String name, String path ) { soundlib.loadSound( name, path ); }
protected void playSound( String name ) { soundlib.playSound( name ); }
protected boolean remove() { return remove ; }
protected void destroy() { remove = true; }
protected void explode() { playAnimation( animationlib.getAnimation( "explosion" ) ); destroy(); }
}
Java:
package de.androbin.lib.games;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.JPanel;
public class World extends JPanel implements KeyListener, Runnable, Serializable {
// Deklarationen
private static final long serialVersionUID = 1L;
protected ArrayList<Sprite> objects = new ArrayList<Sprite>();
protected ArrayList<Mob > mobs = new ArrayList<Mob >();
protected Player player = new Player( "", "", Direction.Down, 0, 0, 0, 0 );
protected BufferedImage background;
protected AnimationLib animationlib = new AnimationLib();
protected SoundLib soundlib = new SoundLib ();
// Konstruktoren
public World() { }
public World( Player player ) { this.player = player; new Thread( this ).start(); }
// Methoden
public void changeBackground( BufferedImage background ) { this.background = background; }
public void addObject( Sprite s ) { objects.add( s ); }
public void addMob ( Mob m ) { mobs .add( m ); }
public boolean moveTo( Sprite s, Direction dir ) {
for ( int i = 0; i < objects.size(); i++ ) if ( !s.checkCollision( objects.get( i ) ) ) return false;
for ( int i = 0; i < mobs .size(); i++ ) if ( !s.checkCollision( mobs .get( i ) ) ) return false;
s.moveTo( dir ); return true;
}
public void moveAt( Sprite s, int x, int y ) { s.moveTo( x, y ); }
@Override
public void paintComponent( Graphics g ) {
super.paintComponent( g );
Graphics2D g2 = (Graphics2D) g;
g.drawImage( background, 0, 0, getWidth(), getHeight(), null );
for ( int i = 0; i < objects.size(); i++ ) { objects.get( i ).paintComponent( g2 ); }
for ( int i = 0; i < mobs .size(); i++ ) { mobs .get( i ).paintComponent( g2 ); }
player .paintComponent( g2 );
}
public void addAnimation( String name, ArrayList<BufferedImage> animation ) { animationlib. addAnimation( name, animation ); }
public void loadAnimation( String name, String path ) { animationlib.loadAnimation( name, path ); }
public void playAnimation( Sprite s , ArrayList<BufferedImage> animation ) { s.playAnimation( animation ); }
public void loadSound( String name, String path ) { soundlib.loadSound( name, path ); }
public void playSound( String name ) { soundlib.playSound( name ); }
public void loopSound( String name ) { soundlib.loopSound( name ); }
public void stopLoopingSounds( ) { soundlib.stopLoopingSounds( ); }
@Override
public void run() {
while ( true ) {
try { Thread.sleep( 500 ); } catch ( InterruptedException e ) { e.printStackTrace(); }
for ( int i = 0; i < objects.size(); i++ ) if ( objects.get( i ).remove() ) objects.remove( i );
for ( int i = 0; i < mobs .size(); i++ ) if ( mobs .get( i ).remove() ) mobs .remove( i );
for ( int i = 0; i < mobs .size(); i++ ) moveTo( mobs.get( i ), Mob.randomDir() );
repaint();
}
}
@ Override
public void keyPressed( KeyEvent e ) {
switch ( e.getKeyCode() ) {
case KeyEvent.VK_W : moveTo( player, Direction.Up ); break;
case KeyEvent.VK_A : moveTo( player, Direction.Left ); break;
case KeyEvent.VK_S : moveTo( player, Direction.Down ); break;
case KeyEvent.VK_D : moveTo( player, Direction.Right ); break;
case KeyEvent.VK_UP : moveTo( player, Direction.Up ); break;
case KeyEvent.VK_DOWN : moveTo( player, Direction.Down ); break;
case KeyEvent.VK_LEFT : moveTo( player, Direction.Left ); break;
case KeyEvent.VK_RIGHT : moveTo( player, Direction.Right ); break;
}
}
@ Override
public void keyReleased( KeyEvent e ) { }
@ Override
public void keyTyped( KeyEvent e ) { }
}
[TIPP]
Inspiriert dazu wurde ich durch Quaxli's Spiele-Tutorial
[/TIPP]
Im Anhang befindet sich außerdem der zugehörige Eclipse-workspace opcorn: