initial import from svn without history
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.settings
|
||||||
|
.cproject
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
|
BIN
bin/Balls.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/Game$BorderBehaviour.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/Game.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/Loader.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/AirHockey.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/Billiard.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/ChainRxn.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/Demo.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/Dodge.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/Golf.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/InkBall.class
Normal file
BIN
bin/de/steffenvogel/balls/controller/mode/Pong.class
Normal file
BIN
bin/de/steffenvogel/balls/model/Ball.class
Normal file
BIN
bin/de/steffenvogel/balls/model/BallList.class
Normal file
BIN
bin/de/steffenvogel/balls/model/Barrier.class
Normal file
BIN
bin/de/steffenvogel/balls/model/BarrierList.class
Normal file
BIN
bin/de/steffenvogel/balls/model/HighScore.class
Normal file
BIN
bin/de/steffenvogel/balls/model/Hole.class
Normal file
BIN
bin/de/steffenvogel/balls/model/HoleList.class
Normal file
BIN
bin/de/steffenvogel/balls/model/Level$VirtualDimension.class
Normal file
BIN
bin/de/steffenvogel/balls/model/Level.class
Normal file
BIN
bin/de/steffenvogel/balls/model/Renderable.class
Normal file
BIN
bin/de/steffenvogel/balls/model/ServerHighScore.class
Normal file
BIN
bin/de/steffenvogel/balls/model/State$Status.class
Normal file
BIN
bin/de/steffenvogel/balls/model/State.class
Normal file
BIN
bin/de/steffenvogel/balls/view/Field.class
Normal file
BIN
bin/de/steffenvogel/balls/view/Gui.class
Normal file
BIN
bin/de/steffenvogel/balls/view/MenuBar.class
Normal file
BIN
bin/de/steffenvogel/balls/view/Sound.class
Normal file
BIN
bin/de/steffenvogel/balls/view/StatusBar.class
Normal file
BIN
bin/de/steffenvogel/util/Vector2d.class
Normal file
BIN
icons/InkBall_Vista_Icon.png
Normal file
After Width: | Height: | Size: 44 KiB |
1218
icons/icons.svg
Normal file
After Width: | Height: | Size: 57 KiB |
3
levels/billiard/level.xml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<level><balls><ball color="-16750849" mass="3141593.0" size="2000"><position x="59318" y="37073"/><orientation x="-499" y="237"/></ball><ball color="-16750849" mass="3141593.0" size="2000"><position x="70920" y="20750"/><orientation x="-480" y="-230"/></ball><ball color="-16750849" mass="3141593.0" size="2000"><position x="21080" y="31760"/><orientation x="-370" y="-140"/></ball></balls><holes/><barriers><barrier><ball color="-1" mass="1.0E10" size="75"><position x="17100" y="26600"/><orientation x="0" y="0"/></ball><ball color="-1" mass="1.0E10" size="75"><position x="50900" y="14400"/><orientation x="0" y="0"/></ball></barrier></barriers>
|
||||||
|
<size width="800" height="400"></size></level>
|
21
server/config.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$config['db']['host'] = 'localhost';
|
||||||
|
$config['db']['user'] = 'steffen';
|
||||||
|
$config['db']['pw'] = 'qU4rK5m1n1m4l';
|
||||||
|
$config['db']['db'] = 'st_ranking';
|
||||||
|
$config['db']['table'] = '2dballs';
|
||||||
|
|
||||||
|
$config['games'] = array( 'AirHockey',
|
||||||
|
'Billiard',
|
||||||
|
'ChainRxn',
|
||||||
|
'Demo',
|
||||||
|
'Dodge',
|
||||||
|
'Golf',
|
||||||
|
'InkBall',
|
||||||
|
'Pong');
|
||||||
|
|
||||||
|
$config['xml']['version'] = '1.0';
|
||||||
|
$config['xml']['encoding'] = 'UTF-8';
|
||||||
|
|
||||||
|
?>
|
30
server/get.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'init.php';
|
||||||
|
|
||||||
|
if (!in_array($_REQUEST['game'], $config['games'])) {
|
||||||
|
die('Unknown game!');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$result = mysql_query('SELECT * FROM ' . $config['db']['table'] . ' WHERE game = \'' . $_REQUEST['game'] . '\' ORDER BY score DESC', $link);
|
||||||
|
|
||||||
|
$doc = new DOMDocument($config['xml']['version'], $config['xml']['encoding']);
|
||||||
|
|
||||||
|
$highScores = $doc->createElement('highscores');
|
||||||
|
$highScores->setAttribute('game', $_REQUEST['game']);
|
||||||
|
$doc->appendChild($highScores);
|
||||||
|
|
||||||
|
$rank = 1;
|
||||||
|
while ($row = mysql_fetch_assoc($result)) {
|
||||||
|
$highScore = $doc->createElement('highscore');
|
||||||
|
$highScore->setAttribute('id', $row['id']);
|
||||||
|
$highScore->setAttribute('rank', $rank++);
|
||||||
|
$highScores->appendChild($highScore);
|
||||||
|
|
||||||
|
foreach (array('date', 'nick', 'score', 'time') as $tagName) {
|
||||||
|
$highScore->appendChild($doc->createElement($tagName, $row[$tagName]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
15
server/init.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'config.php';
|
||||||
|
|
||||||
|
$link = mysql_connect($config['db']['host'], $config['db']['user'], $config['db']['pw']);
|
||||||
|
if (!$link) {
|
||||||
|
die('Not connected : ' . mysql_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
$selected = mysql_select_db($config['db']['db'], $link);
|
||||||
|
if (!$selected) {
|
||||||
|
die ('Can\'t use foo : ' . mysql_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
5
server/submit.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'init.php';
|
||||||
|
|
||||||
|
?>
|
BIN
sounds/click1.wav
Executable file
17
src/Balls.java
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import de.steffenvogel.balls.controller.Loader;
|
||||||
|
import de.steffenvogel.balls.controller.mode.Demo;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Gui;
|
||||||
|
|
||||||
|
public class Balls {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
State state = new State(); // Model
|
||||||
|
Level level = new Level(); // Model
|
||||||
|
Gui gui = new Gui(level, state); // View
|
||||||
|
Loader loader = new Loader(level, state, gui); // Controller
|
||||||
|
|
||||||
|
loader.load(Demo.class);
|
||||||
|
}
|
||||||
|
}
|
189
src/de/steffenvogel/balls/controller/Game.java
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
package de.steffenvogel.balls.controller;
|
||||||
|
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.awt.event.MouseWheelListener;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.model.State.Status;
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
public abstract class Game extends TimerTask implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener {
|
||||||
|
public enum BorderBehaviour {
|
||||||
|
REFLECT, BEAM, REMOVE
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Level level;
|
||||||
|
protected State state;
|
||||||
|
|
||||||
|
public BorderBehaviour borderBehaviour = BorderBehaviour.REMOVE;
|
||||||
|
|
||||||
|
public boolean collisionWithBalls, collisionWithBarriers;
|
||||||
|
public boolean beamBalls;
|
||||||
|
public boolean resizable;
|
||||||
|
public int gravity = 150000;
|
||||||
|
public double friction;
|
||||||
|
|
||||||
|
public Game(Level level, State state) {
|
||||||
|
this.level = level;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void ballCollision(Ball b1, Ball b2);
|
||||||
|
|
||||||
|
protected abstract void ballInHole(Ball ball, Hole hole);
|
||||||
|
|
||||||
|
protected abstract void barrierCollision(Ball ball, Barrier barrier);
|
||||||
|
|
||||||
|
synchronized protected void process() {
|
||||||
|
for (Ball b : level.balls) {
|
||||||
|
if (b.orientation.length() > Ball.getMaxSpeed()) {
|
||||||
|
b.orientation = b.orientation.scMultp(Ball.getMaxSpeed() / b.orientation.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.position.x < -b.size || b.position.x > level.size.width + b.size || b.position.y < -b.size || b.position.y > level.size.height + b.size) {
|
||||||
|
level.balls.remove(b);
|
||||||
|
System.out.println("ball lost!");
|
||||||
|
} else {
|
||||||
|
b.move(1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Ball b : level.balls) {
|
||||||
|
processBall(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void processBall(Ball b) {
|
||||||
|
// border behaviour
|
||||||
|
switch (this.borderBehaviour) {
|
||||||
|
case BEAM:
|
||||||
|
if (b.position.x < 0)
|
||||||
|
b.position.x += level.size.width;
|
||||||
|
else if (b.position.x > level.size.width)
|
||||||
|
b.position.x = 0;
|
||||||
|
|
||||||
|
if (b.position.y < 0)
|
||||||
|
b.position.y += level.size.height;
|
||||||
|
else if (b.position.y > level.size.height)
|
||||||
|
b.position.y = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REFLECT:
|
||||||
|
if (b.position.x < b.size) {
|
||||||
|
float back = 1 - ((b.size - b.position.x) / (float) b.orientation.x);
|
||||||
|
b.move(-back);
|
||||||
|
b.orientation.x *= -1;
|
||||||
|
b.move(back);
|
||||||
|
}
|
||||||
|
else if (b.position.x > level.size.width - b.size) {
|
||||||
|
float back = 1 - ((b.size - level.size.width + b.position.x) / (float) b.orientation.x);
|
||||||
|
b.move(-back);
|
||||||
|
b.orientation.x *= -1;
|
||||||
|
b.move(back);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.position.y < b.size) {
|
||||||
|
float back = 1 - ((b.size - b.position.y) / (float) b.orientation.y);
|
||||||
|
b.move(-back);
|
||||||
|
b.orientation.y *= -1;
|
||||||
|
b.move(back);
|
||||||
|
}
|
||||||
|
else if (b.position.y > level.size.height - b.size) {
|
||||||
|
float back = 1 - ((b.size - level.size.height + b.position.y) / (float) b.orientation.y);
|
||||||
|
b.move(-back);
|
||||||
|
b.orientation.y *= -1;
|
||||||
|
b.move(back);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REMOVE:
|
||||||
|
// std behavior. ball already has been removed!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collision with other balls
|
||||||
|
if (collisionWithBalls) {
|
||||||
|
for (ListIterator<Ball> it = level.balls.listIterator(level.balls.indexOf(b) + 1); it.hasNext();) {
|
||||||
|
Ball b2 = it.next();
|
||||||
|
|
||||||
|
if (b.checkCollision(b2)) {
|
||||||
|
// backsteppin
|
||||||
|
int i = 0;
|
||||||
|
float backStepSize = (float) 1 / 10;
|
||||||
|
while (b.checkCollision(b2) && i <= 10) { // TODO check for infinity loop
|
||||||
|
b.move(-backStepSize);
|
||||||
|
b2.move(-backStepSize);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
b.collide(b2); // collision
|
||||||
|
ballCollision(b, b2); // hook for gamemodes
|
||||||
|
b.move(backStepSize * i); // undo backsteppin
|
||||||
|
b2.move(backStepSize * i); // undo backsteppin
|
||||||
|
|
||||||
|
|
||||||
|
// alternative
|
||||||
|
Vector2d v = b2.orientation.sub(b.orientation);
|
||||||
|
Vector2d bp = v.scMultp(v.length() / b.orientation.Multp(v));
|
||||||
|
Vector2d b2p = v.scMultp(v.length() / b2.orientation.Multp(v));
|
||||||
|
Vector2d n = b2p.sub(bp);
|
||||||
|
|
||||||
|
float back = s
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collision with barriers
|
||||||
|
if (collisionWithBarriers) {
|
||||||
|
for (Barrier barrier : level.barriers) {
|
||||||
|
if (b.checkCollision(barrier)) {
|
||||||
|
|
||||||
|
// TODO check for infinity loop
|
||||||
|
int i = 0;
|
||||||
|
float backStepSize = (float) 1 / 10;
|
||||||
|
while (b.checkCollision(barrier) && i <= 10) {
|
||||||
|
b.move(-backStepSize);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
b.collide(barrier); //collision
|
||||||
|
barrierCollision(b, barrier); // hook for gamemodes
|
||||||
|
b.move(backStepSize * i); // undo backsteppin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collision with holes
|
||||||
|
for (Hole hole : level.holes) {
|
||||||
|
if (hole.position.distance(b.position) < (hole.size - b.size)) {
|
||||||
|
level.balls.remove(b);
|
||||||
|
ballInHole(b, hole);
|
||||||
|
} else if (this.gravity != 0) {
|
||||||
|
hole.gravitate(b, this.gravity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reibung
|
||||||
|
if (b.orientation.length() < 5) {
|
||||||
|
b.stop();
|
||||||
|
} else {
|
||||||
|
b.orientation = b.orientation.scMultp(friction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
synchronized (state) {
|
||||||
|
if (state.status == Status.RUNNING) {
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
230
src/de/steffenvogel/balls/controller/Loader.java
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
package de.steffenvogel.balls.controller;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.ComponentListener;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.awt.event.MouseWheelListener;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowListener;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.util.Timer;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.mode.AirHockey;
|
||||||
|
import de.steffenvogel.balls.controller.mode.Billiard;
|
||||||
|
import de.steffenvogel.balls.controller.mode.ChainRxn;
|
||||||
|
import de.steffenvogel.balls.controller.mode.Demo;
|
||||||
|
import de.steffenvogel.balls.controller.mode.Dodge;
|
||||||
|
import de.steffenvogel.balls.controller.mode.Golf;
|
||||||
|
import de.steffenvogel.balls.controller.mode.InkBall;
|
||||||
|
import de.steffenvogel.balls.controller.mode.Pong;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Gui;
|
||||||
|
|
||||||
|
public class Loader implements WindowListener, ComponentListener {
|
||||||
|
private State state;
|
||||||
|
private Level level;
|
||||||
|
private Gui gui;
|
||||||
|
private Timer timer;
|
||||||
|
public Game game; // Sub-Controller
|
||||||
|
|
||||||
|
private abstract class StateAction extends AbstractAction {
|
||||||
|
private static final long serialVersionUID = -3159579754353760125L;
|
||||||
|
protected State state;
|
||||||
|
|
||||||
|
public StateAction(State state, String title) {
|
||||||
|
super(title);
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LoadAction extends AbstractAction {
|
||||||
|
private static final long serialVersionUID = 5692117074325799909L;
|
||||||
|
Class<?> game;
|
||||||
|
Loader loader;
|
||||||
|
|
||||||
|
public LoadAction(Loader loader, Class<?> game) {
|
||||||
|
super(game.getSimpleName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ImageIcon ico = new ImageIcon(Gui.class.getResource("images/" + game.getSimpleName().toLowerCase() + ".png"));
|
||||||
|
ico.setImage(ico.getImage().getScaledInstance(16, 16, Image.SCALE_DEFAULT));
|
||||||
|
|
||||||
|
this.putValue(Action.SMALL_ICON, ico);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.game = game;
|
||||||
|
this.loader = loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
this.loader.load(this.game);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Loader(Level level, State state, Gui gui) {
|
||||||
|
this.level = level;
|
||||||
|
this.state = state;
|
||||||
|
this.gui = gui;
|
||||||
|
|
||||||
|
gui.field.addComponentListener(this);
|
||||||
|
gui.addWindowListener(this);
|
||||||
|
|
||||||
|
this.loadActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadActions() {
|
||||||
|
gui.menuBar.mnGame.add(new StateAction(this.state, "Starten") {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
this.state.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gui.menuBar.mnGame.add(new StateAction(this.state, "Pausieren") {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
this.state.pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gui.menuBar.mnGame.addSeparator();
|
||||||
|
gui.menuBar.mnGame.add(new AbstractAction("Beenden") {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, AirHockey.class));
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, Billiard.class));
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, ChainRxn.class));
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, Demo.class));
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, Dodge.class));
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, Golf.class));
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, InkBall.class));
|
||||||
|
gui.menuBar.smLoad.add(new LoadAction(this, Pong.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(Class<?> game) {
|
||||||
|
// remove listeners
|
||||||
|
for (MouseListener listener : gui.field.getListeners(MouseListener.class)) gui.field.removeMouseListener(listener);
|
||||||
|
for (MouseMotionListener listener : gui.field.getListeners(MouseMotionListener.class)) gui.field.removeMouseMotionListener(listener);
|
||||||
|
for (MouseWheelListener listener : gui.field.getListeners(MouseWheelListener.class)) gui.field.removeMouseWheelListener(listener);
|
||||||
|
for (KeyListener listener : gui.getListeners(KeyListener.class)) gui.removeKeyListener(listener);
|
||||||
|
|
||||||
|
|
||||||
|
// create timer thread
|
||||||
|
if (this.timer != null) {
|
||||||
|
this.timer.cancel();
|
||||||
|
this.timer.purge();
|
||||||
|
}
|
||||||
|
this.timer = new Timer("controller");
|
||||||
|
|
||||||
|
// reset level and state
|
||||||
|
this.level.load();
|
||||||
|
this.state.reset();
|
||||||
|
this.state.game = game;
|
||||||
|
this.state.nick = JOptionPane.showInputDialog("Bitte gebe deinen Namen an", this.state.nick);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class<?> partypes[] = new Class[2];
|
||||||
|
partypes[0] = Level.class;
|
||||||
|
partypes[1] = State.class;
|
||||||
|
Constructor<?> ctor = game.getConstructor(partypes);
|
||||||
|
Object arglist[] = new Object[2];
|
||||||
|
arglist[0] = level;
|
||||||
|
arglist[1] = state;
|
||||||
|
this.game = (Game) ctor.newInstance(arglist);
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// add listeners
|
||||||
|
gui.field.addMouseListener(this.game);
|
||||||
|
gui.field.addMouseMotionListener(this.game);
|
||||||
|
gui.field.addMouseWheelListener(this.game);
|
||||||
|
gui.addKeyListener(this.game);
|
||||||
|
|
||||||
|
this.gui.setIconImage(new ImageIcon(Gui.class.getResource("images/" + game.getSimpleName().toLowerCase() + ".png")).getImage());
|
||||||
|
this.gui.setTitle("2DBalls - " + game.getSimpleName());
|
||||||
|
|
||||||
|
// start
|
||||||
|
this.timer.scheduleAtFixedRate(this.game, 0, 30);
|
||||||
|
state.start();
|
||||||
|
|
||||||
|
System.out.println("game loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowActivated(WindowEvent e) {
|
||||||
|
this.state.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeactivated(WindowEvent e) {
|
||||||
|
this.state.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowOpened(WindowEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentHidden(ComponentEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentMoved(ComponentEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
this.level.size.set(gui.field.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentShown(ComponentEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
128
src/de/steffenvogel/balls/controller/mode/AirHockey.java
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Field;
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
public class AirHockey extends Game {
|
||||||
|
|
||||||
|
private Ball dodger = null;
|
||||||
|
private Vector2d mousePosition;
|
||||||
|
|
||||||
|
public AirHockey(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = false;
|
||||||
|
gravity = 70000;
|
||||||
|
friction = 0.978;
|
||||||
|
borderBehaviour = BorderBehaviour.REFLECT;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
level.balls.add(Ball.random(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void process() {
|
||||||
|
if (this.dodger != null) {
|
||||||
|
dodger.orientation = mousePosition.sub(dodger.position);
|
||||||
|
super.process();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
this.mouseMoved(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
mousePosition = Field.point2Vector(e.getPoint());
|
||||||
|
if (this.dodger == null) {
|
||||||
|
this.dodger = new Ball(mousePosition, new Vector2d(0, 0), 20 * Field.VIRTUAL_RESOLUTION, 0, Color.red);
|
||||||
|
while (!level.balls.add(this.dodger));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
113
src/de/steffenvogel/balls/controller/mode/Billiard.java
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.BallList;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Gui;
|
||||||
|
|
||||||
|
public class Billiard extends Game {
|
||||||
|
private BallList full, half;
|
||||||
|
private Ball white, black;
|
||||||
|
|
||||||
|
public Billiard(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = true;
|
||||||
|
gravity = 50000;
|
||||||
|
friction = 0.98;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
110
src/de/steffenvogel/balls/controller/mode/ChainRxn.java
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Gui;
|
||||||
|
|
||||||
|
public class ChainRxn extends Game {
|
||||||
|
|
||||||
|
public ChainRxn(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = true;
|
||||||
|
gravity = 70000;
|
||||||
|
friction = 0.99;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
224
src/de/steffenvogel/balls/controller/mode/Demo.java
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Field;
|
||||||
|
import de.steffenvogel.balls.view.Sound;
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
public class Demo extends Game {
|
||||||
|
private Ball pressed, moved;
|
||||||
|
private Barrier barrier;
|
||||||
|
|
||||||
|
public Demo(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = true;
|
||||||
|
resizable = true;
|
||||||
|
gravity = 15000;
|
||||||
|
friction = 1;
|
||||||
|
borderBehaviour = BorderBehaviour.REFLECT;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
this.level.balls.add(Ball.random(this.level));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
state.addPoints((int) (b1.size + b2.size)/Field.VIRTUAL_RESOLUTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
state.addPoints(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
//level.barriers.remove(barrier);
|
||||||
|
|
||||||
|
state.addPoints(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
switch (e.getKeyChar()) {
|
||||||
|
case 'r':
|
||||||
|
level.balls.clear();
|
||||||
|
level.barriers.clear();
|
||||||
|
level.holes.clear();
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
for (Ball ball : level.balls)
|
||||||
|
ball.stop();
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
level.save(new File("level.xml"));
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
level.load(new File("level.xml"));
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
level.balls.add(Ball.random(level));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
if (pressed != null) {
|
||||||
|
moved.position = Field.point2Vector(e.getPoint());
|
||||||
|
|
||||||
|
// Snapping
|
||||||
|
if (barrier != null) {
|
||||||
|
Ball snap = null;
|
||||||
|
Vector2d mouse = Field.point2Vector(e.getPoint());
|
||||||
|
|
||||||
|
for (Ball b : level.balls) {
|
||||||
|
if (b.position.distance(mouse) < 2000 && b != moved && b != barrier.start) {
|
||||||
|
snap = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snap != null) {
|
||||||
|
if (level.balls.contains(moved)) {
|
||||||
|
level.balls.remove(moved);
|
||||||
|
}
|
||||||
|
barrier.end = snap;
|
||||||
|
} else {
|
||||||
|
if (level.balls.contains(moved) == false) {
|
||||||
|
level.balls.add(moved);
|
||||||
|
}
|
||||||
|
barrier.end = moved;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed.position.distance(moved.position) > 100 && e.getModifiersEx() == MouseEvent.BUTTON2_DOWN_MASK) {
|
||||||
|
level.barriers.add(new Barrier(pressed, moved));
|
||||||
|
pressed = moved;
|
||||||
|
moved = new Ball(moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
long size;
|
||||||
|
double mass;
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
if (e.getButton() == MouseEvent.BUTTON3 || e.getButton() == MouseEvent.BUTTON2) {
|
||||||
|
size = 1 * Field.VIRTUAL_RESOLUTION;
|
||||||
|
mass = 0;
|
||||||
|
color = Color.green;
|
||||||
|
} else {
|
||||||
|
size = 20 * Field.VIRTUAL_RESOLUTION;
|
||||||
|
mass = Math.round(Math.PI * Math.pow(10 * Field.VIRTUAL_RESOLUTION, 2));
|
||||||
|
color = Ball.getColorFromSize(20 * Field.VIRTUAL_RESOLUTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snapping
|
||||||
|
if (e.getButton() == MouseEvent.BUTTON3 || e.getButton() == MouseEvent.BUTTON2) {
|
||||||
|
Vector2d mouse = Field.point2Vector(e.getPoint());
|
||||||
|
for (Ball b : level.balls) {
|
||||||
|
if (b.position.distance(mouse) < 2000) {
|
||||||
|
pressed = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed == null) {
|
||||||
|
pressed = new Ball(Field.point2Vector(e.getPoint()), new Vector2d(0, 0), size, mass, color);
|
||||||
|
}
|
||||||
|
moved = new Ball(pressed);
|
||||||
|
|
||||||
|
// TODO check collision between start and endpoint of barrier
|
||||||
|
if (level.balls.checkCollision(pressed) == false) {
|
||||||
|
if (e.getButton() == MouseEvent.BUTTON3 || e.getButton() == MouseEvent.BUTTON2) {
|
||||||
|
barrier = new Barrier(pressed, moved);
|
||||||
|
level.barriers.add(barrier);
|
||||||
|
} else if (e.getButton() == MouseEvent.BUTTON1) {
|
||||||
|
level.balls.add(pressed);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pressed = null;
|
||||||
|
moved = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
if (pressed != null) {
|
||||||
|
if (barrier == null) {
|
||||||
|
pressed.orientation = pressed.position.sub(moved.position).scMultp(0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pressed = null;
|
||||||
|
moved = null;
|
||||||
|
barrier = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
if (pressed != null) {
|
||||||
|
if (pressed.size + 2 * Field.VIRTUAL_RESOLUTION * e.getWheelRotation() > Ball.minSize && pressed.size + 2 * Field.VIRTUAL_RESOLUTION * e.getWheelRotation() < Ball.maxSize) {
|
||||||
|
pressed.size += 2 * e.getWheelRotation() * Field.VIRTUAL_RESOLUTION;
|
||||||
|
pressed.mass = Math.PI * Math.pow(pressed.size, 2);
|
||||||
|
pressed.color = Ball.getColorFromSize(pressed.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
134
src/de/steffenvogel/balls/controller/mode/Dodge.java
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
import javax.swing.Timer;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.model.State.Status;
|
||||||
|
import de.steffenvogel.balls.view.Field;
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
public class Dodge extends Game implements ActionListener {
|
||||||
|
|
||||||
|
private Ball dodger;
|
||||||
|
long lastAdded = System.currentTimeMillis();
|
||||||
|
|
||||||
|
public Dodge(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = false;
|
||||||
|
gravity = 70000;
|
||||||
|
friction = 1.00002;
|
||||||
|
borderBehaviour = BorderBehaviour.REFLECT;
|
||||||
|
|
||||||
|
dodger = new Ball(new Vector2d(0, 0), new Vector2d(0, 0), 20 * Field.VIRTUAL_RESOLUTION, 0, Color.red);
|
||||||
|
level.balls.add(dodger);
|
||||||
|
|
||||||
|
new Timer(3000, this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
dodger.position = Field.point2Vector(e.getPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
if (b1 == dodger || b2 == dodger) {
|
||||||
|
state.gameOver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (state.status == Status.RUNNING) {
|
||||||
|
level.balls.add(Ball.random(level));
|
||||||
|
state.addPoints(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
114
src/de/steffenvogel/balls/controller/mode/Golf.java
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Gui;
|
||||||
|
|
||||||
|
public class Golf extends Game {
|
||||||
|
|
||||||
|
public Golf(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = true;
|
||||||
|
borderBehaviour = BorderBehaviour.REMOVE;
|
||||||
|
gravity = 70000;
|
||||||
|
friction = 0.99;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
level.balls.add(Ball.random(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
170
src/de/steffenvogel/balls/controller/mode/InkBall.java
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
import de.steffenvogel.balls.view.Field;
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
public class InkBall extends Game {
|
||||||
|
|
||||||
|
private Ball pressed, moved;
|
||||||
|
private Barrier barrier;
|
||||||
|
|
||||||
|
public InkBall(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = true;
|
||||||
|
gravity = 70000;
|
||||||
|
borderBehaviour = BorderBehaviour.BEAM;
|
||||||
|
|
||||||
|
level.holes.add(new Hole(new Vector2d(Math.round(level.size.width / 2), Math.round(level.size.height / 2)), 3000, 6000));
|
||||||
|
|
||||||
|
while (!level.balls.add(Ball.random(level)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// Snapping
|
||||||
|
Vector2d mouse = Field.point2Vector(e.getPoint());
|
||||||
|
for (Ball b : level.balls) {
|
||||||
|
if (b.position.distance(mouse) < 2000) {
|
||||||
|
pressed = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed == null) {
|
||||||
|
pressed = new Ball(Field.point2Vector(e.getPoint()), new Vector2d(0, 0), 1 * Field.VIRTUAL_RESOLUTION, 0, Color.white);
|
||||||
|
}
|
||||||
|
moved = new Ball(pressed);
|
||||||
|
|
||||||
|
// TODO check collision between start and endpoint of barrier
|
||||||
|
if (level.balls.checkCollision(pressed) == false) {
|
||||||
|
barrier = new Barrier(pressed, moved);
|
||||||
|
level.barriers.add(barrier);
|
||||||
|
} else {
|
||||||
|
pressed = null;
|
||||||
|
moved = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
if (pressed != null) {
|
||||||
|
moved.position = Field.point2Vector(e.getPoint());
|
||||||
|
|
||||||
|
// Snapping
|
||||||
|
if (barrier != null) {
|
||||||
|
Ball snap = null;
|
||||||
|
Vector2d mouse = Field.point2Vector(e.getPoint());
|
||||||
|
|
||||||
|
for (Ball b : level.balls) {
|
||||||
|
if (b.position.distance(mouse) < 2000 && b != moved && b != barrier.start) {
|
||||||
|
snap = b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snap != null) {
|
||||||
|
if (level.balls.contains(moved)) {
|
||||||
|
level.balls.remove(moved);
|
||||||
|
}
|
||||||
|
barrier.end = snap;
|
||||||
|
} else {
|
||||||
|
if (level.balls.contains(moved) == false) {
|
||||||
|
level.balls.add(moved);
|
||||||
|
}
|
||||||
|
barrier.end = moved;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed.position.distance(moved.position) > 100 && e.getModifiersEx() == MouseEvent.BUTTON2_DOWN_MASK) {
|
||||||
|
level.barriers.add(new Barrier(pressed, moved));
|
||||||
|
pressed = moved;
|
||||||
|
moved = new Ball(moved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent arg0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent arg0) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
while (!level.balls.add(Ball.random(level)));
|
||||||
|
state.addPoints(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
110
src/de/steffenvogel/balls/controller/mode/Pong.java
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
package de.steffenvogel.balls.controller.mode;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.Game;
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
|
||||||
|
public class Pong extends Game {
|
||||||
|
|
||||||
|
public Pong(Level level, State state) {
|
||||||
|
super(level, state);
|
||||||
|
|
||||||
|
collisionWithBalls = true;
|
||||||
|
collisionWithBarriers = true;
|
||||||
|
gravity = 70000;
|
||||||
|
beamBalls = false;
|
||||||
|
friction = 0.99;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballCollision(Ball b1, Ball b2) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void ballInHole(Ball ball, Hole hole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void barrierCollision(Ball ball, Barrier barrier) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
152
src/de/steffenvogel/balls/model/Ball.java
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.view.Field;
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
|
||||||
|
public class Ball implements Renderable {
|
||||||
|
public long size; // radius
|
||||||
|
|
||||||
|
public static int maxSize = 40 * Field.VIRTUAL_RESOLUTION;
|
||||||
|
public static int minSize = 15 * Field.VIRTUAL_RESOLUTION;
|
||||||
|
private static long minSpeed = 6 * Field.VIRTUAL_RESOLUTION;
|
||||||
|
|
||||||
|
public double mass;
|
||||||
|
public Vector2d orientation; // bearing & speed
|
||||||
|
public Vector2d position; // position
|
||||||
|
public Color color;
|
||||||
|
|
||||||
|
public static long getMaxSpeed() {
|
||||||
|
return (2 * Ball.minSize) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ball(Vector2d position, Vector2d orientation, long size, double mass, Color color) {
|
||||||
|
this.position = position;
|
||||||
|
this.orientation = orientation;
|
||||||
|
this.size = size;
|
||||||
|
this.color = color;
|
||||||
|
this.mass = mass == 0 ? 1e10 : mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ball(Ball ball) {
|
||||||
|
this.position = new Vector2d(ball.position);
|
||||||
|
this.orientation = new Vector2d(ball.orientation);
|
||||||
|
this.size = ball.size;
|
||||||
|
this.color = ball.color;
|
||||||
|
this.mass = ball.mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ball(Element xml) {
|
||||||
|
this.size = new Integer(xml.getAttribute("size"));
|
||||||
|
this.mass = new Double(xml.getAttribute("mass"));
|
||||||
|
this.color = new Color(new Integer(xml.getAttribute("color")));
|
||||||
|
this.position = new Vector2d((Element) xml.getElementsByTagName("position").item(0));
|
||||||
|
this.orientation = new Vector2d((Element) xml.getElementsByTagName("orientation").item(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(float steps) {
|
||||||
|
position.x += Math.round(orientation.x * steps);
|
||||||
|
position.y += Math.round(orientation.y * steps);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public Ball random(Level level) {
|
||||||
|
Random rnd = new Random();
|
||||||
|
|
||||||
|
// speed
|
||||||
|
long speed = rnd.nextLong();
|
||||||
|
if (speed < 0)
|
||||||
|
speed *= -1;
|
||||||
|
if (speed >= (getMaxSpeed() - minSpeed))
|
||||||
|
speed %= (getMaxSpeed() - minSpeed);
|
||||||
|
|
||||||
|
speed += minSpeed;
|
||||||
|
speed /= 3;
|
||||||
|
|
||||||
|
// orientation
|
||||||
|
Vector2d orientation = new Vector2d(rnd.nextInt(), rnd.nextInt());
|
||||||
|
orientation = orientation.scMultp(speed / (double) orientation.length());
|
||||||
|
|
||||||
|
// position
|
||||||
|
Vector2d position = new Vector2d(Ball.maxSize + Math.round(rnd.nextDouble() * (level.size.width - 2 * Ball.maxSize)), Ball.maxSize + Math.round(rnd.nextDouble() * (level.size.height - 2 * Ball.maxSize)));
|
||||||
|
long size = Ball.minSize + rnd.nextInt(Ball.maxSize - Ball.minSize);
|
||||||
|
|
||||||
|
double mass = Math.PI * Math.pow(size, 2);
|
||||||
|
Color color = Ball.getColorFromSize(size);
|
||||||
|
|
||||||
|
return new Ball(position, orientation, size, mass, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element xml = doc.createElement("ball");
|
||||||
|
xml.setAttribute("size", String.valueOf(size));
|
||||||
|
xml.setAttribute("mass", String.valueOf(mass));
|
||||||
|
xml.setAttribute("color", String.valueOf(color.getRGB()));
|
||||||
|
xml.appendChild(position.toXml("position", doc));
|
||||||
|
xml.appendChild(orientation.toXml("orientation", doc));
|
||||||
|
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color getColorFromSize(long size) {
|
||||||
|
return Color.getHSBColor((size - Ball.minSize) / (float) Ball.maxSize, 1f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkCollision(Ball b) {
|
||||||
|
if (position.distance(b.position) <= size + b.size && b != this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkCollision(Barrier barrier) {
|
||||||
|
Vector2d z = barrier.start.position.sub(position);
|
||||||
|
Vector2d r = barrier.end.position.sub(barrier.start.position);
|
||||||
|
|
||||||
|
double d = Math.sqrt(2*z.x*r.x*z.y*r.y + Math.pow(r.x, 2)*Math.pow(size, 2) - Math.pow(r.x, 2)*Math.pow(z.y, 2) - Math.pow(r.y, 2)*Math.pow(z.x, 2) + Math.pow(r.y, 2)*Math.pow(size, 2));
|
||||||
|
|
||||||
|
double t1 = (-(z.Multp(r)) + d) / (float) r.sqLength();
|
||||||
|
double t2 = -(z.Multp(r) + d) / (float) r.sqLength();
|
||||||
|
|
||||||
|
if (((t1 > 0 && t1 < 1) || (t2 > 0 && t2 < 1)) && this != barrier.start && this != barrier.end) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void collide(Ball b) {
|
||||||
|
Vector2d q = position.sub(b.position);
|
||||||
|
Vector2d n = new Vector2d(-q.y, q.x);
|
||||||
|
Vector2d p = orientation.sub(b.orientation).scMultp(mass);
|
||||||
|
|
||||||
|
Vector2d pr = q.scMultp(q.Multp(p) / (double) q.sqLength());
|
||||||
|
Vector2d pt = n. scMultp(n.Multp(p) / (double) n.sqLength());
|
||||||
|
|
||||||
|
orientation = pt.add(pr.scMultp((mass - b.mass) / (mass + b.mass))).scMultp(1 / mass).add(b.orientation);
|
||||||
|
b.orientation = pr.scMultp((2 * b.mass) / (mass + b.mass)).scMultp(1 / b.mass).add(b.orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void collide(Barrier barrier) {
|
||||||
|
Vector2d q = barrier.end.position.sub(barrier.start.position);
|
||||||
|
Vector2d n = new Vector2d(-q.y, q.x);
|
||||||
|
Vector2d p = orientation;
|
||||||
|
|
||||||
|
Vector2d pt = q.scMultp(q.Multp(p) / (double) q.sqLength());
|
||||||
|
Vector2d pr = n.scMultp(n.Multp(p) / (double) n.sqLength());
|
||||||
|
orientation = pt.sub(pr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
orientation.x = 0;
|
||||||
|
orientation.y = 0;
|
||||||
|
}
|
||||||
|
}
|
48
src/de/steffenvogel/balls/model/BallList.java
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
public class BallList extends CopyOnWriteArrayList<Ball> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8941543143009333597L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(Ball b) {
|
||||||
|
if (checkCollision(b) == false) {
|
||||||
|
super.add(b);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkCollision(Ball b) {
|
||||||
|
boolean collision = false;
|
||||||
|
for (Ball ball : this) {
|
||||||
|
if (b.checkCollision(ball)) {
|
||||||
|
collision = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
for (Ball ball : this) {
|
||||||
|
remove(ball);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element xmlBalls = doc.createElement("balls");
|
||||||
|
|
||||||
|
for (Ball ball : this) {
|
||||||
|
xmlBalls.appendChild(ball.toXml(doc));
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlBalls;
|
||||||
|
}
|
||||||
|
}
|
26
src/de/steffenvogel/balls/model/Barrier.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class Barrier implements Renderable {
|
||||||
|
public Ball start, end;
|
||||||
|
|
||||||
|
public Barrier(Ball start, Ball end) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO unused ?
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element xml = doc.createElement("barrier");
|
||||||
|
|
||||||
|
xml.appendChild(start.toXml(doc));
|
||||||
|
xml.appendChild(end.toXml(doc));
|
||||||
|
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
}
|
66
src/de/steffenvogel/balls/model/BarrierList.java
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
public class BarrierList extends CopyOnWriteArrayList<Barrier> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8921059530813919037L;
|
||||||
|
|
||||||
|
BallList balls;
|
||||||
|
|
||||||
|
public BarrierList(BallList balls) {
|
||||||
|
this.balls = balls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(Barrier barrier) {
|
||||||
|
balls.add(barrier.start);
|
||||||
|
balls.add(barrier.end);
|
||||||
|
return super.add(barrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Barrier barrier) {
|
||||||
|
super.remove(barrier);
|
||||||
|
balls.remove(barrier.start);
|
||||||
|
balls.remove(barrier.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
for (Barrier barrier : this) {
|
||||||
|
remove(barrier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element xmlBarriers = doc.createElement("barriers");
|
||||||
|
BallList barrierBalls = new BallList();
|
||||||
|
|
||||||
|
/*for (Barrier barrier : this) {
|
||||||
|
xmlBarriers.appendChild(barrier.toXml(doc));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// TODO complete xml generation
|
||||||
|
for (Barrier barrier : this) {
|
||||||
|
for (Barrier subBarrier : this) {
|
||||||
|
if (barrier.start == subBarrier.start) {
|
||||||
|
barrierBalls.add(barrier.start);
|
||||||
|
}
|
||||||
|
if (barrier.start == subBarrier.end) {
|
||||||
|
barrierBalls.add(subBarrier.start);
|
||||||
|
barrierBalls.add(barrier.start);
|
||||||
|
barrierBalls.add(barrier.end);
|
||||||
|
}
|
||||||
|
if (barrier.end == subBarrier.start) {
|
||||||
|
}
|
||||||
|
if (barrier.end == subBarrier.end) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlBarriers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
src/de/steffenvogel/balls/model/HighScore.java
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
public class HighScore {
|
||||||
|
|
||||||
|
public State list[];
|
||||||
|
}
|
42
src/de/steffenvogel/balls/model/Hole.java
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
public class Hole implements Renderable {
|
||||||
|
|
||||||
|
public Vector2d position;
|
||||||
|
public int size;
|
||||||
|
public double mass;
|
||||||
|
|
||||||
|
public Hole(Vector2d position, int size, double mass) {
|
||||||
|
this.position = position;
|
||||||
|
this.size = size;
|
||||||
|
this.mass = mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Hole(Element xml) {
|
||||||
|
this.size = new Integer(xml.getAttribute("size"));
|
||||||
|
this.position = new Vector2d((Element) xml.getElementsByTagName("position").item(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element xml = doc.createElement("hole");
|
||||||
|
xml.setAttribute("size", new Integer(size).toString());
|
||||||
|
xml.appendChild(position.toXml("position", doc));
|
||||||
|
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO geschwindigkeit bei iteration beachten!
|
||||||
|
public void gravitate(Ball b, int gravity) {
|
||||||
|
double r2 = position.sqDistance(b.position);
|
||||||
|
if (mass / (double) r2 > 1 / (double) gravity) {
|
||||||
|
Vector2d r = position.sub(b.position);
|
||||||
|
b.orientation = b.orientation.add(r.scMultp(gravity * (1 / r.length())).scMultp(mass / r2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/de/steffenvogel/balls/model/HoleList.java
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
public class HoleList extends CopyOnWriteArrayList<Hole> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 379892301442116885L;
|
||||||
|
|
||||||
|
public HoleList() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element xmlHoles = doc.createElement("holes");
|
||||||
|
|
||||||
|
for (Hole hole : this) {
|
||||||
|
xmlHoles.appendChild(hole.toXml(doc));
|
||||||
|
}
|
||||||
|
|
||||||
|
return xmlHoles;
|
||||||
|
}
|
||||||
|
}
|
126
src/de/steffenvogel/balls/model/Level.java
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.view.Field;
|
||||||
|
|
||||||
|
@SuppressWarnings("restriction")
|
||||||
|
public class Level extends Observable {
|
||||||
|
public BallList balls = new BallList();
|
||||||
|
public BarrierList barriers = new BarrierList(balls);
|
||||||
|
public HoleList holes = new HoleList();
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
public boolean resizable;
|
||||||
|
|
||||||
|
public VirtualDimension size;
|
||||||
|
|
||||||
|
public Level() {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VirtualDimension {
|
||||||
|
public long width, height;
|
||||||
|
|
||||||
|
public VirtualDimension(long width, long height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VirtualDimension() {
|
||||||
|
width = height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Dimension dim) {
|
||||||
|
width = dim.width * Field.VIRTUAL_RESOLUTION;
|
||||||
|
height = dim.height * Field.VIRTUAL_RESOLUTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dimension toDimension() {
|
||||||
|
return new Dimension(Math.round(width / Field.VIRTUAL_RESOLUTION), Math.round(height / Field.VIRTUAL_RESOLUTION));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
this.size = new VirtualDimension(80000, 60000);
|
||||||
|
|
||||||
|
this.balls.clear();
|
||||||
|
this.barriers.clear();
|
||||||
|
this.holes.clear();
|
||||||
|
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(File file) {
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder builder;
|
||||||
|
try {
|
||||||
|
builder = factory.newDocumentBuilder();
|
||||||
|
Document document = builder.parse(file);
|
||||||
|
|
||||||
|
balls.clear();
|
||||||
|
holes.clear();
|
||||||
|
barriers.clear();
|
||||||
|
|
||||||
|
NodeList xmlBalls = document.getElementsByTagName("ball");
|
||||||
|
for (int i = 0; i < xmlBalls.getLength(); i++) {
|
||||||
|
Element xml = (Element) xmlBalls.item(i);
|
||||||
|
balls.add(new Ball(xml));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList xmlBarriers = document.getElementsByTagName("barrier");
|
||||||
|
for (int i = 0; i < xmlBarriers.getLength(); i++) {
|
||||||
|
Element xml = (Element) xmlBarriers.item(i);
|
||||||
|
barriers.add(new Barrier(balls.get(Integer.valueOf(xml.getAttribute("start"))), balls.get(Integer.valueOf(xml.getAttribute("end")))));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList xmlHoles = document.getElementsByTagName("hole");
|
||||||
|
for (int i = 0; i < xmlHoles.getLength(); i++) {
|
||||||
|
Element xml = (Element) xmlHoles.item(i);
|
||||||
|
holes.add(new Hole(xml));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(File file) {
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder builder;
|
||||||
|
try {
|
||||||
|
builder = factory.newDocumentBuilder();
|
||||||
|
Document doc = builder.newDocument();
|
||||||
|
|
||||||
|
Element xmlLevel = doc.createElement("level");
|
||||||
|
doc.appendChild(xmlLevel);
|
||||||
|
|
||||||
|
xmlLevel.appendChild(balls.toXml(doc));
|
||||||
|
xmlLevel.appendChild(holes.toXml(doc));
|
||||||
|
xmlLevel.appendChild(barriers.toXml(doc));
|
||||||
|
|
||||||
|
XMLSerializer serializer = new XMLSerializer();
|
||||||
|
serializer.setOutputCharStream(new java.io.FileWriter(file));
|
||||||
|
serializer.serialize(doc);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
src/de/steffenvogel/balls/model/Renderable.java
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
public interface Renderable {
|
||||||
|
|
||||||
|
}
|
5
src/de/steffenvogel/balls/model/ServerHighScore.java
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
public class ServerHighScore extends HighScore {
|
||||||
|
|
||||||
|
}
|
83
src/de/steffenvogel/balls/model/State.java
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package de.steffenvogel.balls.model;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.controller.mode.Demo;
|
||||||
|
|
||||||
|
public class State extends Observable implements ActionListener {
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
RUNNING, PAUSED, STOPPED
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int TIME_RESOLUTION = 10;
|
||||||
|
|
||||||
|
public Class<?> game;
|
||||||
|
public int score;
|
||||||
|
public String nick;
|
||||||
|
|
||||||
|
public long time; // playtime in ms;
|
||||||
|
public Status status;
|
||||||
|
|
||||||
|
public int level;
|
||||||
|
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
public State() {
|
||||||
|
timer = new Timer(TIME_RESOLUTION, this);
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
this.stop();
|
||||||
|
this.score = 0;
|
||||||
|
this.time = 0;
|
||||||
|
this.game = Demo.class;
|
||||||
|
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void gameOver() {
|
||||||
|
JOptionPane.showMessageDialog(null, "Sorry! Du hast verloren!",
|
||||||
|
"GameOver", JOptionPane.WARNING_MESSAGE);
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pause() {
|
||||||
|
this.status = Status.PAUSED;
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
this.status = Status.STOPPED;
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
this.status = Status.RUNNING;
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPoints(int points) {
|
||||||
|
score += points;
|
||||||
|
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
this.time += TIME_RESOLUTION;
|
||||||
|
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
}
|
146
src/de/steffenvogel/balls/view/Field.java
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
package de.steffenvogel.balls.view;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.image.VolatileImage;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.model.Ball;
|
||||||
|
import de.steffenvogel.balls.model.Barrier;
|
||||||
|
import de.steffenvogel.balls.model.Hole;
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.util.Vector2d;
|
||||||
|
|
||||||
|
public class Field extends Component implements Runnable, Observer {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public static final int VIRTUAL_RESOLUTION = 100;
|
||||||
|
|
||||||
|
private Level level;
|
||||||
|
|
||||||
|
VolatileImage backBuffer = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the default constructor
|
||||||
|
*/
|
||||||
|
public Field(Level level) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.level = level;
|
||||||
|
this.setSize(level.size.toDimension());
|
||||||
|
}
|
||||||
|
|
||||||
|
void createBackBuffer() {
|
||||||
|
if (backBuffer != null) {
|
||||||
|
backBuffer.flush();
|
||||||
|
backBuffer = null;
|
||||||
|
}
|
||||||
|
backBuffer = createVolatileImage(getWidth(), getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
System.out.println("render thread started");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
repaint();
|
||||||
|
try {
|
||||||
|
Thread.sleep(20);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawBall(Graphics g, Ball ball, boolean drawVec) {
|
||||||
|
g.setColor(ball.color);
|
||||||
|
g.fillOval(vPixel2Pixel(ball.position.x - ball.size),
|
||||||
|
vPixel2Pixel(ball.position.y - ball.size),
|
||||||
|
vPixel2Pixel(2 * ball.size), vPixel2Pixel(2 * ball.size));
|
||||||
|
|
||||||
|
if (drawVec) {
|
||||||
|
drawVector(g, ball.position, ball.orientation, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int vPixel2Pixel(long vPixel) {
|
||||||
|
return Math.round(vPixel / VIRTUAL_RESOLUTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long pixel2vPixel(int vPixel) {
|
||||||
|
return vPixel * VIRTUAL_RESOLUTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Point vector2Point(Vector2d vec) {
|
||||||
|
return new Point(vPixel2Pixel(vec.x), vPixel2Pixel(vec.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2d point2Vector(Point point) {
|
||||||
|
return new Vector2d(pixel2vPixel(point.x), pixel2vPixel(point.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
if (backBuffer == null) {
|
||||||
|
createBackBuffer();
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
int valCode = backBuffer.validate(getGraphicsConfiguration());
|
||||||
|
if (valCode == VolatileImage.IMAGE_RESTORED) { }
|
||||||
|
else if (valCode == VolatileImage.IMAGE_INCOMPATIBLE || backBuffer.getWidth() != this.getWidth() || backBuffer.getHeight() != this.getHeight()) {
|
||||||
|
createBackBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics2D gOff = (Graphics2D) backBuffer.getGraphics();
|
||||||
|
gOff.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
gOff.setColor(Color.black);
|
||||||
|
gOff.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
|
||||||
|
for (Hole hole : level.holes) {
|
||||||
|
gOff.setColor(Color.white);
|
||||||
|
gOff.fillOval(vPixel2Pixel(hole.position.x - hole.size),
|
||||||
|
vPixel2Pixel(hole.position.y - hole.size),
|
||||||
|
vPixel2Pixel(2 * hole.size), vPixel2Pixel(2 * hole.size));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Barrier barrier : level.barriers) {
|
||||||
|
drawVector(gOff, barrier.start.position, barrier.end.position
|
||||||
|
.sub(barrier.start.position), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Ball ball : level.balls) {
|
||||||
|
gOff.setColor(Color.white);
|
||||||
|
drawBall(gOff, ball, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawImage(backBuffer, 0, 0, this);
|
||||||
|
} while (backBuffer.contentsLost());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawVector(Graphics g, Vector2d pos, Vector2d vec,
|
||||||
|
boolean arrow) {
|
||||||
|
g.setColor(Color.white);
|
||||||
|
g.drawLine(vPixel2Pixel(pos.x), vPixel2Pixel(pos.y), vPixel2Pixel(pos.x
|
||||||
|
+ vec.x), vPixel2Pixel(pos.y + vec.y));
|
||||||
|
|
||||||
|
// TODO draw Vectorarrows
|
||||||
|
/*
|
||||||
|
* if (arrow) { int al = 1000; int ax =
|
||||||
|
*
|
||||||
|
* g.drawLine(vPixel2Pixel(pos.x + vec.x), vPixel2Pixel(pos.y + vec.y),
|
||||||
|
* 0, 0); g.drawLine(vPixel2Pixel(pos.x + vec.x), vPixel2Pixel(pos.y +
|
||||||
|
* vec.y), 0, 0); }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
Level level = (Level) o;
|
||||||
|
this.setPreferredSize(level.size.toDimension());
|
||||||
|
}
|
||||||
|
} // @jve:decl-index=0:visual-constraint="10,10"
|
56
src/de/steffenvogel/balls/view/Gui.java
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package de.steffenvogel.balls.view;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.model.Level;
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
|
||||||
|
public class Gui extends JFrame implements Observer {
|
||||||
|
private static final long serialVersionUID = -7936315723587248620L;
|
||||||
|
|
||||||
|
public Field field;
|
||||||
|
public MenuBar menuBar;
|
||||||
|
public StatusBar statusBar;
|
||||||
|
|
||||||
|
public Gui(Level level, State state) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// window
|
||||||
|
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
this.setLayout(new BorderLayout());
|
||||||
|
this.setIconImage(new ImageIcon(Gui.class.getResource("images/balls.png")).getImage());
|
||||||
|
this.setTitle("2DBalls");
|
||||||
|
|
||||||
|
// menu
|
||||||
|
menuBar = new MenuBar();
|
||||||
|
this.setJMenuBar(menuBar);
|
||||||
|
|
||||||
|
// field
|
||||||
|
field = new Field(level);
|
||||||
|
this.add(field, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// statusbar
|
||||||
|
statusBar = new StatusBar();
|
||||||
|
this.add(statusBar, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
// render thread
|
||||||
|
Thread thread = new Thread(field);
|
||||||
|
thread.start();
|
||||||
|
this.setVisible(true);
|
||||||
|
|
||||||
|
// observer
|
||||||
|
state.addObserver(statusBar);
|
||||||
|
level.addObserver(this);
|
||||||
|
level.addObserver(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
this.pack();
|
||||||
|
}
|
||||||
|
}
|
29
src/de/steffenvogel/balls/view/MenuBar.java
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package de.steffenvogel.balls.view;
|
||||||
|
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
|
||||||
|
public class MenuBar extends JMenuBar {
|
||||||
|
private static final long serialVersionUID = 3710344818603193892L;
|
||||||
|
|
||||||
|
public JMenu smLoad, mnGame, mnHelp;
|
||||||
|
|
||||||
|
public MenuBar() {
|
||||||
|
mnGame = new JMenu("Spiel");
|
||||||
|
mnHelp = new JMenu("?");
|
||||||
|
|
||||||
|
smLoad = new JMenu("starten");
|
||||||
|
JMenuItem miQuit = new JMenuItem("Beenden");
|
||||||
|
JMenuItem miHelp = new JMenuItem("Hilfe");
|
||||||
|
JMenuItem miAbout = new JMenuItem("Über");
|
||||||
|
|
||||||
|
this.add(mnGame);
|
||||||
|
this.add(mnHelp);
|
||||||
|
|
||||||
|
mnGame.add(smLoad);
|
||||||
|
mnGame.add(miQuit);
|
||||||
|
mnHelp.add(miHelp);
|
||||||
|
mnHelp.add(miAbout);
|
||||||
|
}
|
||||||
|
}
|
61
src/de/steffenvogel/balls/view/Sound.java
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package de.steffenvogel.balls.view;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
import javax.sound.sampled.AudioInputStream;
|
||||||
|
import javax.sound.sampled.AudioSystem;
|
||||||
|
import javax.sound.sampled.Clip;
|
||||||
|
import javax.sound.sampled.DataLine;
|
||||||
|
|
||||||
|
public class Sound implements Runnable {
|
||||||
|
AudioInputStream stream;
|
||||||
|
DataLine.Info info;
|
||||||
|
Clip clip;
|
||||||
|
private ThreadPoolExecutor executor;
|
||||||
|
|
||||||
|
public Sound(File file) {
|
||||||
|
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(200);
|
||||||
|
executor = new ThreadPoolExecutor(30, 200, 1, TimeUnit.SECONDS, queue);
|
||||||
|
|
||||||
|
|
||||||
|
try{
|
||||||
|
stream = AudioSystem.getAudioInputStream(file);
|
||||||
|
AudioFormat af = stream.getFormat();
|
||||||
|
int size = (int) (af.getFrameSize() * stream.getFrameLength());
|
||||||
|
byte[] audio = new byte[size];
|
||||||
|
info = new DataLine.Info(Clip.class, af, size);
|
||||||
|
stream.read(audio, 0, size);
|
||||||
|
|
||||||
|
clip = (Clip) AudioSystem.getLine(info);
|
||||||
|
clip.open(af, audio, 0, size);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void play() {
|
||||||
|
if (executor.getPoolSize() < 200) {
|
||||||
|
executor.execute(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("triggered" + executor.getTaskCount() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
clip.setFramePosition(0);
|
||||||
|
clip.start();
|
||||||
|
clip.stop();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO: handle exception
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
src/de/steffenvogel/balls/view/StatusBar.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package de.steffenvogel.balls.view;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
import de.steffenvogel.balls.model.State;
|
||||||
|
|
||||||
|
public class StatusBar extends JPanel implements Observer {
|
||||||
|
|
||||||
|
public JLabel score, nick, time, level, game;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public StatusBar() {
|
||||||
|
this.setPreferredSize(new Dimension(-1, 22));
|
||||||
|
this.setBorder(LineBorder.createGrayLineBorder());
|
||||||
|
this.setLayout(new GridLayout(1, 4));
|
||||||
|
|
||||||
|
score = new JLabel();
|
||||||
|
nick = new JLabel();
|
||||||
|
time = new JLabel();
|
||||||
|
level = new JLabel();
|
||||||
|
game = new JLabel();
|
||||||
|
|
||||||
|
this.add(score);
|
||||||
|
this.add(nick);
|
||||||
|
this.add(time);
|
||||||
|
this.add(level);
|
||||||
|
this.add(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(State state) {
|
||||||
|
score.setText("Punkte: " + state.score);
|
||||||
|
nick.setText("Nick: " + state.nick);
|
||||||
|
level.setText("Level: " + state.level);
|
||||||
|
|
||||||
|
SimpleDateFormat tf = new SimpleDateFormat("mm:ss.SSS");
|
||||||
|
|
||||||
|
time.setText("Zeit: " + tf.format(state.time));
|
||||||
|
game.setText("Spiel: " + state.game.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
this.update((State) o);
|
||||||
|
}
|
||||||
|
}
|
BIN
src/de/steffenvogel/balls/view/images/airhockey.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
src/de/steffenvogel/balls/view/images/balls.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
src/de/steffenvogel/balls/view/images/billiard.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
src/de/steffenvogel/balls/view/images/chainrxn.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
src/de/steffenvogel/balls/view/images/demo.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
src/de/steffenvogel/balls/view/images/dodge.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
src/de/steffenvogel/balls/view/images/golf.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
src/de/steffenvogel/balls/view/images/inkball.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/de/steffenvogel/balls/view/images/pong.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
81
src/de/steffenvogel/util/Vector2d.java
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package de.steffenvogel.util;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
public class Vector2d {
|
||||||
|
|
||||||
|
public long x, y;
|
||||||
|
|
||||||
|
public Vector2d(long x, long y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2d(Vector2d vec) {
|
||||||
|
this.x = vec.x;
|
||||||
|
this.y = vec.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2d(Element xml) {
|
||||||
|
this.x = new Long(xml.getAttribute("x"));
|
||||||
|
this.y = new Long(xml.getAttribute("y"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2d(Point point) {
|
||||||
|
this.x = point.x;
|
||||||
|
this.y = point.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long sqLength() {
|
||||||
|
return x*x+y*y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double length() {
|
||||||
|
return Math.sqrt(sqLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double distance(Vector2d to) {
|
||||||
|
return Math.sqrt(sqDistance(to));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long sqDistance(Vector2d to) {
|
||||||
|
Vector2d vec = this.sub(to);
|
||||||
|
|
||||||
|
return vec.sqLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2d add(Vector2d sum) {
|
||||||
|
return new Vector2d(x+sum.x, y+sum.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2d sub(Vector2d sum) {
|
||||||
|
return new Vector2d(x-sum.x, y-sum.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2d neg() {
|
||||||
|
return new Vector2d(-x, -y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Multp(Vector2d prod) {
|
||||||
|
return this.x * prod.x + this.y * prod.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2d scMultp(double scalar) {
|
||||||
|
return new Vector2d(Math.round(x * scalar), Math.round(y * scalar));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "(" + x + "," + y + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element toXml(String tagName, Document doc) {
|
||||||
|
Element elm = doc.createElement(tagName);
|
||||||
|
elm.setAttribute("x", new Long(x).toString());
|
||||||
|
elm.setAttribute("y", new Long(y).toString());
|
||||||
|
|
||||||
|
return elm;
|
||||||
|
}
|
||||||
|
}
|