Hallo,
hab mal ne Jar-Datei im Anhang !
Die Bilddatei dazu muss in einen Ordner "images" !
So nunja, also wie ich weitere Barrieren erstelle wei0 ich schon, ich brauch nun noch
einen Zufallsgenerator, der per Zufall in der Game-Schleife die current_barrier ermittelt !
und denn brauche ich noch eine Kollisionsabfrage ! und evtl. noch eine Möglichkeit, dass diese Barrieren rotieren.
naja aber wie schon gesagt, das ist erstmal noch Schnickschnack !
PS: 2 Barrieren habe ich ja schon !
Hier nochmal der aktuelle Code zum Verständnis:
FallOfBall.java
[HIGHLIGHT="Java"]import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FallOfBall extends JPanel
{
private static final long serialVersionUID = 1L;
public static boolean run = false;
public static void main(String [] args)
{
new FallOfBall(800,800);
}
public FallOfBall(int w, int h){
this.setPreferredSize(new Dimension(800,800));
this.setBackground(Color.white);
JLabel label = new JLabel(new ImageIcon("images/logo.jpg"));
label.setSize(new Dimension(800,222));
label.add(this);
label.setLocation(0,0);
JLabel caption = new JLabel("Copyright © 2009 by H@ckz0r");
caption.setSize(new Dimension(800,50));
caption.setFont(new Font("Tw Cen MT",Font.PLAIN,18));
caption.add(this);
caption.setLocation(280, 700);
JButton but = new JButton();
but.setSize(new Dimension(794,40));
but.setBackground(Color.white);
but.setBorderPainted(true);
but.setRolloverEnabled(true);
but.setText(" Start ");
but.setFont(new Font("Tw Cen MT",Font.ITALIC,34));
but.setForeground(Color.black);
but.setLocation(0,400);
JFrame frame = new JFrame("Fall Of Ball - Pre-Alpha 0.12");
frame.setLocation(100,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(caption);
frame.add(but);
frame.add(label);
frame.add(this);
frame.setSize(new Dimension(800, 800));
frame.setResizable(false);
frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
frame.setVisible(true);
while(run==false){
but.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e){
run = true;
}
}
);
}
if(run==true) {
frame.remove(but);
frame.remove(label);
frame.remove(this);
frame.remove(caption);
final Function func = new Function(1100);
func.setHelpGraphicsEnabled(false);
frame.add(func);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
func.stopAnimation();
}
});
frame.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
func.startAnimation();
}
});
}
}
}[/HIGHLIGHT]
und hier die Function.java
[HIGHLIGHT="Java"]package rocketgame;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class Function extends JPanel
{
private static final long serialVersionUID = 1L;
protected float tunnel_radius = 0;
protected float tunnel_diameter = 0;
/** diese Variable speichert den Center des vorderen Kreises (den grünen).
Diese Variable wird nach der Mausbewegung angepasst. */
protected Point2D.Float tunnel_front_center = new Point2D.Float(0f, 0f);
/** der graue Kreis */
protected MovementCircle movement_circle = null;
/** Eine Liste mit allen verfügbaren Barrieren */
protected ArrayList<AbstractBarrier> barrier_list = null;
/** die aktuell angezeigte Barriere */
protected AbstractBarrier current_barrier = null;
/** die Positionen der Seitenlinien auf dem Vorderkreis (den grünen) */
protected float [] tinnel_side_positions = {
360f*(1.0f/6.0f),
360f*(2.0f/6.0f),
360f*(3.0f/6.0f),
360f*(4.0f/6.0f),
360f*(5.0f/6.0f),
360f*(6.0f/6.0f)
};
protected Thread thread = null;
protected TunnelRunner tunnel_runner = null;
protected boolean help_graphics_enabled = false;
public Function(float tunnel_radius)
{
super(null);
this.tunnel_radius = tunnel_radius;
this.tunnel_diameter = tunnel_radius*2;
this.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
this.addMouseMotionListener(new MouseController());
movement_circle = new MovementCircle();
barrier_list = new ArrayList<AbstractBarrier>();
barrier_list.add(new BigHoleBarrier());
barrier_list.add(new RectangleHoleBarrier());
// hier wird eine Barriere als aktive (die sichtbar ist) ausgewählt
current_barrier = barrier_list.get(0);
}
public boolean isHelpGraphicsEnabled()
{
return help_graphics_enabled;
}
public void setHelpGraphicsEnabled(boolean enabled)
{
this.help_graphics_enabled = enabled;
}
////////////////////////////////////////////////////////////////////////
// Paint
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Dimension size = getSize();
Graphics2D g2 = (Graphics2D)g;
// zwei Graphics2D Objekte für verschiedene Arten der Darstellung
// ein Graphics2D für das Interface, beginnt oben links
Graphics2D g2_interface = (Graphics2D)g2.create();
// ein Graphics2D für den Tunnel, beginnt in der mitte des Bildschirms
Graphics2D g2_tunnel = (Graphics2D)g2.create();
g2_tunnel.setBackground(Color.white);
g2_tunnel.clearRect(0, 0, size.width, size.height);
g2_tunnel.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2_tunnel.translate(size.width/2, size.height/2);
g2_interface.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
paintTunnelSideLines(g2_tunnel, Color.black);
paintBarrier(g2_tunnel, movement_circle);
paintBarrier(g2_tunnel, current_barrier);
if(help_graphics_enabled)
paintHelpGraphics(g2_tunnel);
paintSpeed(g2_interface);
}
protected void paintSpeed(Graphics2D g2)
{
g2.setColor(Color.red);
g2.setFont(new Font("Tw Cen MT",Font.PLAIN,20));
g2.drawString("Speed: " + getspeed() + " %", 20, 20);
g2.drawString("Speed-Factor: " + getspeedfactor(), 20, 40);
g2.drawString("Zeit: " + gettimeM() + ":" + gettimeS(), 700, 20);
}
// die nächsten zwei Funktionen zeichnen die Seitenlinien
protected void paintTunnelSideLines(Graphics2D g2, Color color)
{
g2.setColor(Color.black);
paintTunnelSideLine(g2, 0);
paintTunnelSideLine(g2, 1);
paintTunnelSideLine(g2, 2);
paintTunnelSideLine(g2, 3);
paintTunnelSideLine(g2, 4);
paintTunnelSideLine(g2, 5);
}
protected void paintTunnelSideLine(Graphics2D g2,
int side_line_index)
{
Point2D.Float poc = getPointOnCircle(tunnel_front_center,
tunnel_radius,
tinnel_side_positions[side_line_index]);
Line2D.Float base_line = new Line2D.Float(0f, 0f, poc.x, poc.y);
Point2D.Float tp1 = getPointOnLine(base_line, 0.02f);
Point2D.Float tp2 = getPointOnLine(base_line, 0.02f);
Path2D.Float path = new Path2D.Float();
path.moveTo(tp1.x, tp1.y);
path.lineTo(poc.x+tp2.y, poc.y-tp2.x);
path.lineTo(poc.x-tp2.y, poc.y+tp2.x);
path.closePath();
g2.fill(path);
}
// die nächste Funktion zeichnet eine Barriere
protected void paintBarrier(Graphics2D g2, AbstractBarrier barrier)
{
barrier.updateBarrierShapes();
if(barrier instanceof MovementCircle)
{
g2.setColor(Color.gray);
g2.draw(barrier.front);
}
else
{
g2.setColor(new Color(235, 235, 235));
g2.fill(barrier.back);
g2.setColor(Color.black);
g2.draw(barrier.back);
g2.setColor(Color.white);
g2.fill(barrier.front);
g2.setColor(Color.black);
g2.draw(barrier.front);
}
}
// die nächste Funktion zeichnet die Hilfsgrafiken
protected void paintHelpGraphics(Graphics2D g2)
{
g2.setColor(Color.green);
g2.drawOval((int)(-tunnel_radius+tunnel_front_center.x),
(int)(-tunnel_radius+tunnel_front_center.y),
(int)tunnel_diameter,
(int)tunnel_diameter);
g2.setColor(Color.blue);
g2.drawLine(0, 0, (int)tunnel_front_center.x,
(int)tunnel_front_center.y);
g2.setColor(Color.red);
g2.drawLine(-10, 0, 10, 0);
g2.drawLine(0, -10, 0, 10);
}
// Paint END
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Animation & Interactivity
private float speedfactor = (float) 0.0000;
private double speed = 100;
public double speedfactorR;
public double speedR;
public int timeS;
public int timeM;
public double t;
public String string_timeM;
public double time_buffer;
public synchronized void startAnimation()
{
if(thread == null)
{
tunnel_runner = new TunnelRunner();
thread = new Thread(tunnel_runner);
thread.start();
}
}
public synchronized void stopAnimation()
{
if(thread != null)
{
tunnel_runner.loop = false;
thread = null;
}
}
protected class TunnelRunner implements Runnable
{
protected boolean loop = true;
@Override
public void run()
{
time_buffer=System.currentTimeMillis();
// In dieser Schleife werden die Positionen und die Geschwindigkeiten
// der aktiven Elemente (Barriere, Seitenlinien) angepasst
while(loop)
{
if(speed<400.0)
{
speedfactor=(float)(speedfactor+0.0001*2);
speed=speed+(speedfactor/10);
speedfactorR=Math.round(speedfactor*100)/100.00;
speedR=Math.round(speed);
}
// das ist der graue Kreis, der sich asymetrisch zu den Barieren bewegt
// und so ein Gefühl für Bewegung und Geschwindigkeit gibt
movement_circle.barrier_pos = (movement_circle.barrier_pos+0.0042f*(speedfactor+movement_circle.barrier_pos*3.0f)) % 1f;
// hier wird die Position und die Geschwindigkeit eine Barriere angepasst
current_barrier.barrier_pos = (current_barrier.barrier_pos+0.0065f*(speedfactor+current_barrier.barrier_pos*2.0f)) % 1f;
// die Seitenlinienpositionen auf dem Vorderkreis (den grünen) verschieben,
// um den Rotationseffekt zu erzeugen
float side_rotation_speed = 0.2f;
for(int i = 0; i < tinnel_side_positions.length; i++)
tinnel_side_positions
= (tinnel_side_positions + side_rotation_speed) % 360f;
if(timeS<60){
timeS=(int)Math.round(((System.currentTimeMillis()-time_buffer)/100)*100.0)/1000;
}
else{
timeM=timeM+1;
timeS=0;
time_buffer=System.currentTimeMillis();
}
repaint();
try { Thread.sleep(15); }
catch(InterruptedException e) { loop = false; e.printStackTrace(); }
if(current_barrier.barrier_pos==0.5){
for (int i=0; i<1;i++)
{
current_barrier =barrier_list.get((int) Math.floor(2*Math.random()));
System.out.println(current_barrier);
}
}
}
}
}
public double getspeed(){
return this.speedR;
}
public double getspeedfactor(){
return this.speedfactorR;
}
public int gettimeS(){
return this.timeS;
}
public int gettimeM(){
return this.timeM;
}
protected class MouseController extends MouseAdapter
{
@Override
public void mouseMoved(MouseEvent e)
{
super.mouseMoved(e);
Dimension size = getSize();
// tunnel_center.setLocation(e.getX() - size.width/2, e.getY() - size.height/2);
tunnel_front_center.setLocation(-(e.getX() - size.width/2), -(e.getY() - size.height/2));
repaint();
}
}
// Animation & Interactivity END
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Barriers
protected abstract class AbstractBarrier
{
/** Form, welche die Vorderseite eine Barriere darstellt */
protected Shape front = null;
/** Form, welche die Hinterseite eine Barriere darstellt */
protected Shape back = null;
/** Position im Tunnel zwischen 0f (Hinten) und 1f (Vorne).
Kann man auch als Tiefe ansehen */
protected float barrier_pos = 0.5f;
protected abstract void updateBarrierShapes();
}
protected class MovementCircle extends AbstractBarrier
{
@Override
protected void updateBarrierShapes()
{
// 2D Postion im Tunnel anhand der Tiefe ermitteln
Point2D.Float pit = getPointOnLine(0, 0,
tunnel_front_center.x,
tunnel_front_center.y,
barrier_pos);
float barrier_radius = barrier_pos*tunnel_radius;
front = new Ellipse2D.Float(-barrier_radius+pit.x, -barrier_radius+pit.y,
barrier_radius*2, barrier_radius*2);
}
}
protected class BigHoleBarrier extends AbstractBarrier
{
@Override
protected void updateBarrierShapes()
{
// 2D Postion im Tunnel anhand der Tiefe ermitteln
Point2D.Float pit = getPointOnLine(0, 0,
tunnel_front_center.x,
tunnel_front_center.y,
barrier_pos);
// Vorderform für die Barriere aufbauen
float barrier_radius = (barrier_pos*tunnel_radius);
float barrier_diameter = barrier_radius*2;
float hole_radius = barrier_radius*0.9f;
float hole_diameter = hole_radius*2;
Ellipse2D.Float barrier_base = null;
Ellipse2D.Float barrier_hole = null;
Area area = null;
barrier_base = new Ellipse2D.Float(-barrier_radius+pit.x,
-barrier_radius+pit.y,
barrier_diameter,
barrier_diameter);
barrier_hole = new Ellipse2D.Float(-hole_radius+pit.x,
-hole_radius+pit.y,
hole_diameter,
hole_diameter);
area = new Area(barrier_base);
area.subtract(new Area(barrier_hole));
this.front = area;
// Hinterform für die Barriere aufbauen
barrier_radius = barrier_radius*0.96f;
barrier_diameter = barrier_radius*2;
hole_radius = barrier_radius*0.9f;
hole_diameter = hole_radius*2;
barrier_base = new Ellipse2D.Float(-barrier_radius+pit.x,
-barrier_radius+pit.y,
barrier_diameter,
barrier_diameter);
barrier_hole = new Ellipse2D.Float(-hole_radius+pit.x,
-hole_radius+pit.y,
hole_diameter,
hole_diameter);
area = new Area(barrier_base);
area.subtract(new Area(barrier_hole));
this.back = area;
}
}
protected class RectangleHoleBarrier extends AbstractBarrier
{
@Override
protected void updateBarrierShapes()
{
// 2D Postion im Tunnel anhand der Tiefe ermitteln
Point2D.Float pit = getPointOnLine(0, 0,
tunnel_front_center.x,
tunnel_front_center.y,
barrier_pos);
// Vorderform für die Barriere aufbauen
float barrier_radius = (barrier_pos*tunnel_radius);
float barrier_diameter = barrier_radius*2;
float hole_width = barrier_radius*0.7f;
float hole_height = barrier_radius*0.2f;
Ellipse2D.Float barrier_base = null;
Rectangle2D.Float barrier_hole = null;
Area area = null;
barrier_base = new Ellipse2D.Float(-barrier_radius+pit.x,
-barrier_radius+pit.y,
barrier_diameter,
barrier_diameter);
barrier_hole = new Rectangle2D.Float(-hole_width+pit.x,
-hole_height+pit.y,
hole_width*2,
hole_height*2);
area = new Area(barrier_base);
area.subtract(new Area(barrier_hole));
this.front = area;
// Hinterform für die Barriere aufbauen
barrier_radius = barrier_radius*0.96f;
barrier_diameter = barrier_radius*2;
hole_width = barrier_radius*0.7f;
hole_height = barrier_radius*0.2f;
barrier_base = new Ellipse2D.Float(-barrier_radius+pit.x,
-barrier_radius+pit.y,
barrier_diameter,
barrier_diameter);
barrier_hole = new Rectangle2D.Float(-hole_width+pit.x,
-hole_height+pit.y,
hole_width*2,
hole_height*2);
area = new Area(barrier_base);
area.subtract(new Area(barrier_hole));
this.back = area;
}
}
// Barriers END
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Geometric Help Functions
protected static Point2D.Float getPointOnCircle(Point2D.Float center,
float radius, float angle)
{
return getPointOnCircle(center.x, center.y, radius, angle);
}
protected static Point2D.Float getPointOnCircle(float x, float y,
float radius, float angle)
{
return new Point2D.Float(x + (float)(radius*Math.cos(Math.toRadians(angle))),
y + (float)(radius*Math.sin(Math.toRadians(angle))));
}
public static Point2D.Float getPointOnLine(Line2D.Float line,
float t)
{
return getPointOnLine(line.x1, line.y1, line.x2, line.y2, t);
}
public static Point2D.Float getPointOnLine(float x1, float y1,
float x2, float y2,
float t)
{
return new Point2D.Float((x2 - x1)*t + x1,
(y2 - y1)*t + y1);
}
// Geometric Help Functions END
////////////////////////////////////////////////////////////////////////
}[/HIGHLIGHT]
Vielen Dank schonmal im vorraus !
PPS: Ich habe schon einen Zufallsgenerator drin, weiß aber nicht so recht wie bzw. eher wo ich ihn einbinden muss, damit er jeweils nur am Anfang der Röhre (wenn die Barrieren gezeichnet werden) die aktuelle Barriere abfragt !
MFG
Benni