Hey Leute, ich weiß nicht ob ihrs kennt, aber ich will einen kleinen adk bzw Curve Feverklon zaubern.
Das ganze ist ja eigentlich nur ein multiplayer snake mit runder bewegung.
Nun hab ich eine kleine simulation gebastelt, wobei ich aber wieder mal probleme habe:
Ich benutze für den spieler einfach nen path2D, der dann mit einem Basic Stroke gezeichent wird.
Auf tastendruck A (links) und D (rechts) verändert sich der bewegungswinkel. Noch ohne kollisionserkennung und so weiter.
- das ganze läuft von anfang an nicht wirklcih flüssig (es soll später über lan laufen, ist das überhaupt realistisch?)
- nach ungefähr 1 minute, wenn sich eshr viele punkte im Path2D angesammelt haben, läggt es nur noch
(die schlange macht 5 pixel schritte, ungefähr…) - Es gibt, wenn man sich selbst oft schneidet oft schwarze punkte IM stroke
- das ganze sieht trotz antialiasing nicht wirklich antialiased aus…
Könnt ihr mir weiter helfen?
vielen Dank!
Der Code bisher:
Main.java
[spoiler]```package de.skysoldier.adk;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JPanel implements Runnable {
private Player player;
private boolean rotateLeft;
private boolean rotateRight;
private long lastFrame;
private long delta;
public Main(){
JFrame f = new JFrame();
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
addKeyListener(movementListener);
setFocusable(true);
f.add(this);
f.setVisible(true);
Thread t = new Thread(this);
t.start();
}
public void run(){
player = new Player(Color.GREEN.darker());
lastFrame = System.nanoTime();
while(true){
updateTime();
updatePlayer();
repaint();
try{Thread.sleep(5);}catch(Exception e){}
}
}
private void updateTime(){
long thisf = System.nanoTime() - lastFrame;
delta = thisf - lastFrame;
}
private void updatePlayer(){
player.update(delta, rotateLeft, rotateRight);
}
private KeyAdapter movementListener = new KeyAdapter() {
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_A) rotateLeft = true;
if(e.getKeyCode() == KeyEvent.VK_D) rotateRight = true;
}
public void keyReleased(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_A) rotateLeft = false;
if(e.getKeyCode() == KeyEvent.VK_D) rotateRight = false;
}
};
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setStroke(player.getStroke());
g2d.setColor(player.getColor());
g2d.draw(player.getPath());
g2d.setColor(player.getColor().darker());
g2d.fillOval((int) player.getPositionX() - player.getWidth() / 2, (int) player.getPositionY() - player.getWidth() / 2, player.getWidth(), player.getWidth());
g2d.setColor(player.getColor().brighter());
g2d.fillOval((int) player.getPositionX() - player.getWidth() / 4, (int) player.getPositionY() - player.getWidth() / 4, player.getWidth() / 2, player.getWidth() / 2);
}
public static void main(String[] args) {
new Main();
}
}```[/spoiler]
Player.java
[spoiler]```package de.skysoldier.adk;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
public class Player {
private Path2D playerPath;
private BasicStroke playerStroke;
private Color color;
private int width;
private double positionX;
private double positionY;
private double speedX;
private double speedY;
private double movementX;
private double movementY;
private double angle;
private double rotationSpeed;
public Player(Color color){
this.color = color;
this.width = 20;
this.positionX = 400;
this.positionY = 300;
this.speedX = 2.5;
this.speedY = 2.5;
this.rotationSpeed = 0.05;
this.angle = Math.toRadians(0);
playerPath = new GeneralPath();
playerStroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
playerPath.moveTo(positionX, positionY);
}
public void update(long delta, boolean rotateRight, boolean rotateLeft){
if(rotateRight) angle += rotationSpeed * delta / 1e15;
else if(rotateLeft) angle -= rotationSpeed * delta / 1e15;
movementX = Math.cos(angle) * speedX * delta / 1e15;
movementY = Math.sin(angle) * speedY * delta / 1e15;
positionX += movementX;
positionY += movementY;
playerPath.lineTo(positionX, positionY);
}
public void rotate(double angle){
this.angle = Math.toRadians(angle);
}
public int getWidth(){
return width;
}
public double getPositionX(){
return positionX;
}
public double getPositionY(){
return positionY;
}
public double getAngle(){
return angle;
}
public Color getColor(){
return color;
}
public Path2D getPath(){
return playerPath;
}
public Stroke getStroke(){
return playerStroke;
}
}```[/spoiler]
*** Edit ***
Ach ja, ausserdem tritt nach einer weile ab und zu diese exception auf, obwohl mein code persönlich nichts mit arrays am hut hat…
was hat path2d da für probleme??
xception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException
at java.awt.geom.AffineTransform.transform(Unknown Source)
at java.awt.geom.Path2D$Float$TxIterator.currentSegment(Unknown Source)
at sun.dc.DuctusRenderingEngine.getAATileGenerator(Unknown Source)
at sun.java2d.pipe.AAShapePipe.renderPath(Unknown Source)
at sun.java2d.pipe.AAShapePipe.draw(Unknown Source)
at sun.java2d.pipe.PixelToParallelogramConverter.draw(Unknown Source)
at sun.java2d.SunGraphics2D.draw(Unknown Source)
at de.skysoldier.adk.Main.paintComponent(Main.java:72)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1100(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)