Movement while rotating Java - java

Im trying to create a top down space ship rpg and I cant seem to get it to move correctly. It wont turn at the correct angles for example if I have it at say a 70 degree angle it will move at a 45 degree angle. Can anyone help? Im building it in netbeans if you want to test it to see what I mean.
package games;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Rotation extends JPanel implements KeyListener{
private static double i = 0, inc = 0.1, iBase, speed = 0, maxTurnSpeed = 2;
private static int xPos = 100, yPos = 100, width = 100, height = 50;
static boolean pressedA = false, pressedD = false, slowdown = false;
public static void main(String[] args) throws InterruptedException {
System.out.println(i);
JFrame f = new JFrame();
Rotation r = new Rotation();
f.add(new Rotation());
f.setSize(600, 600);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.addKeyListener(r);
while(true){
move();
accelerate();
f.repaint();
Thread.sleep(10);
}
}
public static void move(){
xPos += speed * Math.cos(Math.toRadians(i));
yPos += speed * Math.sin(Math.toRadians(i));
System.out.println(i);
}
public static void accelerate(){
//=========Rotational speed acceleration========
if(i>= 360)
i=0;
if(i<= -360)
i=0;
if(pressedA)
i-=inc;
if(pressedD)
i+=inc;
if(inc<maxTurnSpeed && !slowdown && (pressedA || pressedD))
inc+= 0.01;
if(slowdown && inc>=0.02) {
inc-=0.2;
if(inc <= 0.02){
slowdown = false;
pressedA = false;
pressedD = false;
inc = 0;
}
if(pressedA)
i-=inc;
if(pressedD)
i+=inc;
}
//=========Frontal speed Acceleration=========
//i = Math.round10(i, -2);
//System.out.println(inc);
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setPaint(new Color(150, 150, 150));
g2d.fillRect(20, 20, 80, 50);
g2d.translate(180, -50);
g2d.rotate(Math.toRadians(i), xPos+width/2, yPos+height/2);
g2d.fillRect(xPos, yPos, width, height);
g2d.dispose();
//System.out.println("repainted");
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_W) {
System.out.println("W is pressed");
speed = 2;
slowdown = false;
maxTurnSpeed = 1;
}
if (keyCode == KeyEvent.VK_S) {
System.out.println("S is pressed");
speed = -1;
slowdown = false;
maxTurnSpeed = 1;
}
if (keyCode == KeyEvent.VK_A) {
System.out.println("A is pressed");
slowdown = false;
pressedA = true;
}
if (keyCode == KeyEvent.VK_D) {
System.out.println("D is pressed");
slowdown = false;
pressedD = true;
}
this.i=i;
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
speed = 0;
slowdown = true;
maxTurnSpeed = 2;
}
}

Related

Collision between rectangle and pointed line spinning in swing

Just a small program I quickly made to see if I could perform collisions with a rectangle object and a rotating rectangle object.
Problem arises when rotating rectangle object, the collision box doesn't rotate, only the image rotates.
In this code I tried to use shape object but and performed transformations to it, but was unsuccessful.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
public class test extends JFrame implements Runnable,KeyListener
{
MyDrawPanel playPanel = new MyDrawPanel();
Thread th= new Thread(this);
int w=500, h=539;
Rectangle s1;
Rectangle r1;
int x=50,y=50;
int spx=0;
int spy=0;
int b=0;
int spin=0,spin2=0;
Shape p1;
AffineTransform tx,ax;
public static void main (String [] args)
{
new test();
}
public test()
{
s1= new Rectangle(200,200,106,16);
p1= new Rectangle(200,200,106,16);
r1= new Rectangle(x,y,50,50);
this.setSize(w,h);
this.setVisible(true);
this.setResizable(true);
this.addKeyListener(this);
this.add(playPanel);
playPanel.setDoubleBuffered(true);
th.start();
}
public void keyPressed(KeyEvent e)
{
int key =e.getKeyCode();
if (key == KeyEvent.VK_DOWN)
{
spy=2;
}
if (key == KeyEvent.VK_UP)
{
spy=-2;
}
if (key == KeyEvent.VK_RIGHT)
{
spx=2;
}
if (key == KeyEvent.VK_LEFT)
{
spx=-2;
}
}
public void keyReleased(KeyEvent e)
{
spx=0;
spy=0;
}
public void keyTyped(KeyEvent e)
{}
public void coll()
{
if (r1.getBounds().intersects(p1.getBounds()))
{
b=1;
}
else{b=0;}
}
public void rot()
{
AffineTransform px= new AffineTransform();
px.rotate(Math.toRadians(spin),w/2,h/2);
p1=px.createTransformedShape(s1);
}
///DO TOP HEAD INTERSECT CHECKINGGGGGGGGGGGGGGGGG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public void run ()
{
while (true)
{
rot();
r1.x+=spx;
r1.y+=spy;
spin+=2;
coll();
repaint();
try
{
Thread.sleep (30);
}
catch (InterruptedException ex)
{
}
}
}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (b==1)
{
g2.setColor(Color.RED);
}
AffineTransform old= g2.getTransform();
//g2.rotate(Math.toRadians(spin),
//p1.getBounds().x+8,p1.getBounds().y+8);
g2.fillRect(p1.getBounds().x,p1.getBounds().y,106,16);
g2.setTransform(old);
g2.fillRect(r1.x,r1.y,r1.width,r1.height);
}
}
}
//15.31
/* ADD YOUR CODE HERE */
Used Bresenham's algorithm to find all pixels on a Line2D to detect collision between Rectangle and Line through class LineIterator.
Try like below said source, by increased value of spx and spy with difference value of 4 for moving the square faster:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Iterator;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class RotateRectangleRound extends JFrame implements KeyListener {
private static final long serialVersionUID = 9085168127541601308L;
private Rectangle stableRect;
private int cw = 400, ch = 400;
private boolean collision;
private int spx = 0, spy = 0;
private double radius = 120;
private double angleX = 0, angleY = 0;
private int rotatingVal = 0;
private Line2D line;
private LineIterator iterator;
private Point currentPoint;
private Point2D tp;
private static BasicStroke spinningStroke = new BasicStroke(8);
private static BasicStroke basicStroke = new BasicStroke(1);
private MyPanel panel;
private static boolean startWorker;
private SwingWorker<Void, Void> swingWorker;
public RotateRectangleRound() {
init();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new RotateRectangleRound();
}
});
}
private void init() {
this.setTitle("Rotate Rectangle - Paused");
this.getContentPane().setLayout(new GridLayout(1, 1));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(400, 200, 400, 400);
this.setLayout(new GridLayout(1, 1));
this.addKeyListener(this);
this.setVisible(true);
// getting the window width & height insets explicitly
cw = this.getContentPane().getWidth();
ch = this.getContentPane().getHeight();
// setting the stableRect and movableRect to between of screen except insets
stableRect = new Rectangle(20, 20, 40, 40);
angleX = 192;
angleY = 300;
this.panel = new MyPanel();
this.add(panel);
}
#Override
public void keyTyped(KeyEvent evt) {}
public void keyPressed(KeyEvent evt) {
int key = evt.getKeyCode();
if (key == KeyEvent.VK_DOWN) {
spy = 4;
moveStableRectangle();
} else if (key == KeyEvent.VK_UP) {
spy = -4;
moveStableRectangle();
} else if (key == KeyEvent.VK_RIGHT) {
spx = 4;
moveStableRectangle();
} else if (key == KeyEvent.VK_LEFT) {
spx = -4;
moveStableRectangle();
}
if (key == KeyEvent.VK_SPACE) {
startWorker = (!startWorker);
if (startWorker) {
this.setTitle("Rotate Rectangle");
collision = false;
startRotatingFromPoint();
}else {
this.setTitle("Rotate Rectangle - Paused");
}
}
}
private void moveStableRectangle() {
stableRect.x += spx;
stableRect.y += spy;
repaint();
}
public void keyReleased(KeyEvent evt) {
spx = 0;
spy = 0;
}
private void startRotatingFromPoint() {
swingWorker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
while (startWorker) {
try {
if (rotatingVal == 360)
rotatingVal = 0;
// first getting the angle x, y value for radius 100,
// second adding the half of width & height to rotate
// between screen accordingly with that w & h value
angleX = (Math.sin(Math.toRadians((double) rotatingVal)) * radius) + (cw / 2);
angleY = (Math.cos(Math.toRadians((double) rotatingVal++)) * radius) + (ch / 2);
// calculating collision
collision();
// requesting frame repainting
repaint();
Thread.sleep(10);
} catch (InterruptedException iex) {
iex.printStackTrace();
}
}
return null;
}
};
swingWorker.execute();
}
public void collision() {
if (detectCollision()) {
collision = true;
startWorker = false;
this.setTitle("Rotate Rectangle - Hitted");
} else {
collision = false;
}
}
private boolean detectCollision() {
boolean flag = false;
if(angleX < (cw/2))
line = new Line2D.Double(angleX, angleY, cw / 2, ch / 2);
else
line = new Line2D.Double(cw / 2, ch / 2, angleX, angleY);
//creating a iterator by use of Bresenham's algorithm
iterator = new LineIterator(line);
looperFor:
for (Iterator<Point2D> it = iterator; it.hasNext();) {
//getting Point2D Object of Point Iterator
tp = it.next();
currentPoint = new Point((int) tp.getX(), (int) tp.getY());
if (stableRect.contains(currentPoint)) {
flag = true;
break looperFor;
}
}
//returning the detected collision flag true or false
return flag;
}
class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
#Override
public void paintComponent(Graphics gr) {
Graphics2D g = (Graphics2D) gr;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setStroke(basicStroke);
if (collision)
g.setColor(Color.RED);
g.fillRect(stableRect.x, stableRect.y, stableRect.width, stableRect.height);
g.setStroke(spinningStroke);
g.drawLine(cw / 2, ch / 2, (int) angleX, (int) angleY);
}
}
}
Hope this would help you.

cannot find symbol- class KeyEvent

I am trying to make a brickBreaker game with the help of a video but when I compile I get an error in my public voids that involve KeyEvent towards the bottom of the code.
I get the error as follows:
cannot find symbol-class KeyEvent.
package brickBreaker;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent.*;
import java.awt.event.KeyListener;
import java.util.Timer;
import javax.swing.JPanel;
public class Gameplay extends JPanel implements KeyListener, ActionListener{
private boolean play = false;
private int score = 0;
private int totalBricks = 21;
private Timer time;
private int delay = 8;
private int playerX = 310;
private int ballposX = 120;
private int ballposY = 350;
private int balldirX = -1;
private int balldirY = -2;
private MapGenerator map;
public Gameplay(){
map = new MapGenerator(3, 7);
addKeyListener(this);
addActionListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
// timer = new Timer(delay, this);
// timer.start();
}
public void paint(Graphics g){
//background
g.setColor(Color.black);
g.fillRect(1,1, 692, 592);
//Drawing map
map.draw((Graphics2D)g);
//borders
g.setColor(Color.yellow);
g.fillRect(0,0,3,592);
g.fillRect(0,0,692,3);
g.fillRect(691, 0, 3, 592);
//the paddle
g.setColor(Color.green);
g.fillRect(playerX, 550, 100, 8);
//the ball
g.setColor(Color.yellow);
g.fillOval(ballposX, ballposY, 20, 20);
g.dispose();
}
#Override
public void actionPerformed(ActionEvent e){
timer.start();
if(play){
if(new Rectangle(ballposX, ballposY, 20, 20).intersects(new Rectangle(playerX, 550, 100, 8))){
balldirY = -balldirY;
}
A: for(int i = 0; i < map.map.length; i++){
for(int j = 0; j<map.map[0].length; j++){
if(map.map[i][j] > 0){
int brickX = j* map.brickwidth + 80;
int brickY = i * map.brickheight +50;
int brickwidth = map.brickwidth;
int brickheight = map.brickheight;
Rectangle rect = new Rectangle(brickX, brickY, brickwidth, brickheight);
Rectangle ballRect= new Rectangle(ballposX, ballposY, 20, 20);
Rectangle brickRect = rect;
if(ballRect.intersects(brickRect)){
map.setBrickValue(0, i, j);
totalBricks--;
score += 5;
if(ballposX + 1 <= brickRect.x || ballposX+1 >= brickRect.x+brickRect.width){
balldirX = -balldirX;
} else{
balldirY = -balldirY;
}
break A;
}
}
}
}
ballposX += balldirX;
ballposY+= balldirY;
if(ballposX < 0){
balldirX = -balldirX;
}
if(ballposY < 0){
balldirY = -balldirY;
}
if(ballposX > 670){
balldirX = -balldirX;
}
}
repaint();
}
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
if(playerX >= 600){
playerX = 600;
} else{
moveRight();
}
}
if(e.getKeyCode() == KeyEvent.VK_LEFT){
if(playerX >= 10){
playerX = 10;
} else{
moveLeft();
}
}
}
public void moveRight(){
play = true;
playerX+=20;
}
public void moveLeft(){
play = true;
playerX-=20;
}
}
Change this line import java.awt.event.KeyEvent.*; to this import java.awt.event.KeyEvent;.
EDIT
You need to implement these two methods as well, as they are part of the KeyListener interface.
#Override
public void keyReleased(KeyEvent arg0) {
// TODO
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO
}

SnakeGame how to make the tail follow the head?

I am making a snake game, and I am stuck at where making the tails follow the head. And I heard using an add and remove on the head and tails could make that happen, but I have no idea where to start with that.
Here's my code so far:
Screen.java
public class Screen extends JPanel implements ActionListener, KeyListener {
public static final JLabel statusbar = new JLabel("Default");
public static final int WIDTH = 800, HEIGHT = 800;
Timer t = new Timer(100, this);
int x = 400;
int y = 400;
int size = 5; //increase size if eat
private boolean right = false, left = false, up = false, down = false;
int head = 0;
private LinkedList<BodyPart> snake = new LinkedList<BodyPart>();
private BodyPart b;
public Screen(){
initSnake();
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void update(){
}
public void direction(){
if(right) x+=10;
if(left) x-=10;
if(up) y-=10;
if(down) y+=10;
}
public void trackOutBound(){
if(x < 0 || x > 800 || y < 0 || y > 800) {
x = 400;
y = 400;
}
}
public void initSnake(){
if(snake.size() == 0){
b = new BodyPart(x, y);
for(int i = 0; i < size; i++) {
snake.add(b);
}
System.out.println(snake);
}
}
public static void main(String[] args) {
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(new Color(10, 50, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
for(int i = 0; i < WIDTH / 10; i++) {
g.drawLine(i * 10, 0, i * 10, HEIGHT);
}
for(int i = 0; i < HEIGHT / 10; i++) {
g.drawLine(0, i * 10, WIDTH, i * 10);
}
int tempx = 0, tempy = 0;
int temp = 0;
for(int i = 0; i < size; i++){
if(i == head) {
snake.get(i).x = x;
snake.get(i).y = y;
snake.get(i).draw(g);
g.setColor(Color.blue);
g.fillRect(x, y, 10, 10);
g.setColor(Color.white);
g.drawRect(x, y, 10, 10);
} else if(i > 0 && up) {
snake.get(i).x = x;
snake.get(i).y = y + temp;
snake.get(i).draw(g);
} else if(i > 0 && down) {
snake.get(i).x = x;
snake.get(i).y = y - temp;
snake.get(i).draw(g);
} else if(i > 0 && left) {
snake.get(i).x = x + temp;
snake.get(i).y = y;
snake.get(i).draw(g);
} else if(i > 0 && right) {
snake.get(i).x = x - temp;
snake.get(i).y = y;
snake.get(i).draw(g);
}
temp += 10;
}
/*
if(snake.size() == 5){
snake.add(b);
size += 1;
}
*/
}
#Override
public void actionPerformed(ActionEvent e) {
direction();
trackOutBound();
repaint();
// System.out.println(snake);
statusbar.setText("(" + x + " , " + y + ")");
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT && !left) {
up = false;
down = false;
right = true;
}
if(key == KeyEvent.VK_LEFT && !right) {
up = false;
down = false;
left = true;
}
if(key == KeyEvent.VK_UP && !down) {
left = false;
right = false;
up = true;
}
if(key == KeyEvent.VK_DOWN && !up) {
left = false;
right = false;
down = true;
}
}
#Override
public void keyReleased(KeyEvent e) {}
}
BodyPart.java
public class BodyPart {
int x;
int y;
public BodyPart(int x, int y) {
this.x = x;
this.y = y;
}
public void draw(Graphics g) {
this.x = x;
this.y = y;
g.setColor(Color.red);
g.fillRect(x, y, 10, 10);
g.setColor(Color.white);
g.drawRect(x, y, 10, 10);
}
}
Frame.java
public class Frame extends JPanel {
private static JLabel statusbar = new JLabel("Default");
public void statusbar(){
statusbar = Screen.statusbar;
}
public static void main(String[] args) {
JFrame f = new JFrame();
Screen s = new Screen();
f.add(s);
f.add(statusbar, BorderLayout.SOUTH);
f.setSize(800, 800);
f.setVisible(true);
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Now this code would only make the tails flip to the horizontal or vertical, is it possible to make the tails follow the head by using this code? or I need to change my code?
Thank you
The basic idea is, you need some kind of List which contains ALL the points of the snake. Conceptually, the List would contain virtual coordinates, that is 1x1 would represent a coordinate in virtual space, which presented a place on a virtual board (which would have some wide and height).
You could then translate that to the screen, so this would allow each part of the snake to be larger then a single pixel. So, if each part was 5x5 pixels, then 1x1 would actually be 5x5 in the screen.
Each time the snake moves, you add a new value to the head and remove the last value from tail (assuming it's not growing). When you needed to paint the snake, you would simply iterate over the List, painting each point of the snake.
The following is a simple example, which uses a LinkedList, which pushes a new Point onto the List, making a new head, and removing the last element (the tail) on each cycle.
Which basically boils down to...
snakeBody.removeLast();
snakeBody.push(new Point(xPos, yPos));
As a runnable concept
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Snake {
public static void main(String[] args) {
new Snake();
}
public Snake() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
public enum Direction {
UP, DOWN, LEFT, RIGHT
}
private int xPos, yPos;
private Direction direction = Direction.UP;
private LinkedList<Point> snakeBody = new LinkedList<>();
public TestPane() {
xPos = 100;
yPos = 100;
for (int index = 0; index < 50; index++) {
snakeBody.add(new Point(xPos, yPos));
}
bindKeyStrokeTo("up.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), new MoveAction(Direction.UP));
bindKeyStrokeTo("down.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), new MoveAction(Direction.DOWN));
bindKeyStrokeTo("left.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), new MoveAction(Direction.LEFT));
bindKeyStrokeTo("right.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), new MoveAction(Direction.RIGHT));
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
switch (direction) {
case UP:
yPos--;
break;
case DOWN:
yPos++;
break;
case LEFT:
xPos--;
break;
case RIGHT:
xPos++;
break;
}
if (yPos < 0) {
yPos--;
} else if (yPos > getHeight() - 1) {
yPos = getHeight() - 1;
}
if (xPos < 0) {
xPos--;
} else if (xPos > getWidth() - 1) {
xPos = getWidth() - 1;
}
snakeBody.removeLast();
snakeBody.push(new Point(xPos, yPos));
repaint();
}
});
timer.start();
}
public void bindKeyStrokeTo(String name, KeyStroke keyStroke, Action action) {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(keyStroke, name);
am.put(name, action);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (Point p : snakeBody) {
g2d.drawLine(p.x, p.y, p.x, p.y);
}
g2d.dispose();
}
public class MoveAction extends AbstractAction {
private Direction moveIn;
public MoveAction(Direction direction) {
this.moveIn = direction;
}
#Override
public void actionPerformed(ActionEvent e) {
direction = this.moveIn;
}
}
}
}
Now, this has no collision detection or other functionality, but you can move the snake around and it will follow itself
For snake style movement, you can, from the tail to the head, move each BodyPart position to the position of the BodyPart ahead of it. For the head there is no part ahead so you have to write decision code whether to simply move the same direction as the part before it or a new direction based on input. Then update the screen.

Getting my sprite to face in a certain direction based on Keyboard input - Java Game

So I've pretty much thrown together a basic game in java by following a bunch of different tutorials - the problem is i cant manage to figure out how to get my sprite to move in different directions. Here is the code for my main
package com.game.src.main;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 850;
public static final int HEIGHT = 650;
public static final int SCALE = 1;
public final String TITLE = "Racing Game!";
static ServerSocket serverSocket;
static Socket socket;
static DataOutputStream out;
private boolean running = false;
private Thread thread;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
private BufferedImage spriteSheet = null;
private BufferedImage spriteSheet2 = null;
private BufferedImage background = null;
private BufferedImage MenuBackground = null;
private Player p;
private Player2 p2;
private Menu menu;
public static enum STATE {
MENU,
GAME
};
public static STATE State = STATE.MENU;
public void init() {
BufferedImageLoader loader = new BufferedImageLoader();
try {
spriteSheet = loader.loadImage("/Sprite_Sheet.png");
background = loader.loadImage("/Track.png");
MenuBackground = loader.loadImage("/MenuBG.fw.png");
}
catch (IOException e) {
e.printStackTrace();
}
menu = new Menu();
addKeyListener(new KeyInput(this));
this.addMouseListener(new MouseInput());
p = new Player(365, 500, this);
p2 = new Player2(365, 550, this);
}
private synchronized void start() {
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private synchronized void stop() {
if(!running)
return;
running = false;
try {
thread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(1);
}
public void run() {
init();
long lastTime = System.nanoTime();
final double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int updates = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while(running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if(delta >= 1) {
tick();
updates++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " FPS, TICKS " + frames);
updates = 0;
frames = 0;
}
}
stop();
}
private void tick() {
if(State == STATE.GAME){
p.tick();
p2.tick();
}
}
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
g.drawImage(MenuBackground, 0, 0, null);
if(State == STATE.GAME){
//Drawing the main games background
g.drawImage(background, 0, 0, null);
p.render(g);
p2.render(g);
}
else if(State == STATE.MENU){
menu.render(g);
}
g.dispose();
bs.show();
}
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
if(State == STATE.GAME){
if(key == KeyEvent.VK_RIGHT){
p.setVelX(5);
}
if(key == KeyEvent.VK_D){
p2.setVelX2(5);
}
else if(key == KeyEvent.VK_LEFT) {
p.setVelX(-5);
}
else if(key == KeyEvent.VK_A) {
p2.setVelX2(-5);
}
else if(key == KeyEvent.VK_DOWN) {
p.setVelY(5);
}
else if(key == KeyEvent.VK_S) {
p2.setVelY2(5);
}
else if(key == KeyEvent.VK_UP) {
p.setVelY(-5);
}
else if(key == KeyEvent.VK_W) {
p2.setVelY2(-5);
}
}
}
public void keyReleased(KeyEvent e){
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT){
p.setVelX(0);
}
if(key == KeyEvent.VK_D){
p2.setVelX2(0);
}
else if(key == KeyEvent.VK_LEFT) {
p.setVelX(0);
}
else if(key == KeyEvent.VK_A) {
p2.setVelX2(0);
}
else if(key == KeyEvent.VK_DOWN) {
p.setVelY(0);
}
else if(key == KeyEvent.VK_S) {
p2.setVelY2(0);
}
else if(key == KeyEvent.VK_UP) {
p.setVelY(0);
}
else if(key == KeyEvent.VK_W) {
p2.setVelY2(0);
}
}
public static void main(String args[]) throws Exception {
Game game = new Game();
game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
JFrame frame = new JFrame(game.TITLE);
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
System.out.println("Starting server....");
serverSocket = new ServerSocket(7777);
System.out.println("Server started");
socket = serverSocket.accept();
System.out.println("Connecting from: " + socket.getInetAddress());
out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("This is a test of Java Sockets");
System.out.println("Data has been sent");
}
public BufferedImage getSpriteSheet() {
return spriteSheet;
}
public BufferedImage getSpriteSheet2() {
return spriteSheet2;
}
}
This is my player class
package com.game.src.main;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class Player {
private double x;
private double y;
private double velX = 0;
private double velY = 0;
private BufferedImage player;
BufferedImageLoader loader = new BufferedImageLoader();
BufferedImage SpriteSheet = null;
public Player(double x, double y, Game game) {
this.x = x;
this.y = y;
//New instance of Sprite sheet - reading from buffered image loader
SpriteSheet ss = new SpriteSheet(game.getSpriteSheet());
player = ss.grabImage(1, 1, 50, 50);
try {
SpriteSheet = loader.loadImage("/Sprite_Sheet.png");
}
catch(Exception e) {
e.printStackTrace();
}
}
public void tick() {
x+=velX;
y+=velY;
//Adding basic collision
if(x < 0 + 50) {
x = 0 + 50;
}
if(x >= 850 - 100) {
x = 850 - 100;
}
if(y < 0 + 100) {
y = 0 + 100;
}
if(y >= 650 - 100){
y = 650 - 100;
}
}
public void render(Graphics g){
//Draw Track
Color c1 = Color.green;
g.setColor( c1 );
g.fillRect( 150, 200, 550, 300 ); //grass
Color c2 = Color.black;
g.setColor( c2 );
g.drawRect(50, 100, 750, 500); // outer edge
g.drawRect(150, 200, 550, 300); // inner edge
Color c3 = Color.yellow;
g.setColor( c3 );
g.drawRect( 100, 150, 650, 400 ); // mid-lane marker
Color c4 = Color.white;
g.setColor( c4 );
g.drawLine( 425, 500, 425, 600 ); // start line
g.drawImage(player, (int)x, (int)y, null);
}
public double getX(Graphics g){
return x;
}
public double getY(){
return y;
}
public void setX(double x){
this.x = x;
}
public void setY(double y){
this.y = y;
}
public void setVelX(double velX){
this.velX = velX;
}
public void setVelY(double velY){
this.velY = velY;
}
}
I have two players in this game but i'm really stuck on how i can change the sprites direction by 22.5% in a desired direction so if i pressed the up key for player 1 it would rotate my car 22.5% north etc. I have a sprite sheet with 16 sprites for each player for every change in angle by 22.5% This is really confusing me and i'm not sure how i can implement this,
Thanks for taking the time to look
This is a basic example of spinning a sprite
What this is maintain's a virtual state which the Player object inspects in order to determine how it should be changed accordingly. This separates the action from the result, meaning that it would be possible to substitute the action (arrow up key) with some other action, but still obtain the same result.
This example also uses the key bindings API, which doesn't suffer from the same focus related issues that KeyListener does, but this is a pure Swing API and won't be compatiable with Canvas, but is a nice demonstration ;)
The real magic occurs in the characters paint method...
public void paint(Graphics2D g2d) {
Graphics2D g = (Graphics2D) g2d.create();
AffineTransform at = new AffineTransform();
at.translate(x, y);
at.rotate(Math.toRadians(angle), character.getWidth() / 2, character.getHeight() / 2);
g.transform(at);
g.drawImage(character, 0, 0, null);
}
Basically, this creates a AffineTransformation which is then compounded to produce the result we need. That is, first it's anchor position is translated to the characters x/y position and then rotated about the characters center point. Because it's been translated, we can simply paint the character at 0x0. This much easier then try to calculate the characters rotation anchor somewhere else in virtual space - IMHO
The character is rotated by pressing either the Up or Down arrow keys. While pressed, the character will continue to rotate, this is a feature of the example for demonstration purpose.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class RotateCharater {
public static void main(String[] args) {
new RotateCharater();
}
public RotateCharater() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private DefaultState state;
private Player player;
public TestPane() {
player = new Player();
state = new DefaultState();
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "upKeyPressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "upKeyReleased");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "downKeyPressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "downKeyReleased");
ActionMap am = getActionMap();
am.put("upKeyPressed", new UpKeyAction(state, true));
am.put("upKeyReleased", new UpKeyAction(state, false));
am.put("downKeyPressed", new DownKeyAction(state, true));
am.put("downKeyReleased", new DownKeyAction(state, false));
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
player.update(state);
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
player.paint(g2d);
g2d.dispose();
}
public class UpKeyAction extends AbstractAction {
private DefaultState state;
private boolean pressed;
public UpKeyAction(DefaultState state, boolean pressed) {
this.state = state;
this.pressed = pressed;
}
#Override
public void actionPerformed(ActionEvent e) {
state.setUpKeyPressed(pressed);
}
}
public class DownKeyAction extends AbstractAction {
private DefaultState state;
private boolean pressed;
public DownKeyAction(DefaultState state, boolean pressed) {
this.state = state;
this.pressed = pressed;
}
#Override
public void actionPerformed(ActionEvent e) {
state.setDownKeyPressed(pressed);
}
}
}
public interface State {
public boolean isUpKeyPressed();
public boolean isDownKeyPressed();
}
public class DefaultState implements State {
private boolean upKeyPressed;
private boolean downKeyPressed;
public boolean isDownKeyPressed() {
return downKeyPressed;
}
public boolean isUpKeyPressed() {
return upKeyPressed;
}
public void setDownKeyPressed(boolean downKeyPressed) {
this.downKeyPressed = downKeyPressed;
upKeyPressed = false;
}
public void setUpKeyPressed(boolean upKeyPressed) {
this.upKeyPressed = upKeyPressed;
downKeyPressed = false;
}
}
public class Player {
private BufferedImage character;
private int x = 100 - 32, y = 100 - 32;
private double angle;
public Player() {
try {
character = ImageIO.read(getClass().getResource("/Character.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void paint(Graphics2D g2d) {
Graphics2D g = (Graphics2D) g2d.create();
AffineTransform at = new AffineTransform();
at.translate(x, y);
at.rotate(Math.toRadians(angle), character.getWidth() / 2, character.getHeight() / 2);
g.transform(at);
g.drawImage(character, 0, 0, null);
}
public void update(State state) {
if (state.isUpKeyPressed()) {
angle -= 22.5;
} else if (state.isDownKeyPressed()) {
angle += 22.5;
}
}
}
}
Remember, this is just an example used to present the concept ;)

Grey screen in Netbeans

so i using netbeans, and i'm starting to get into coding games... and i've done this so far with no errors, however when i run it just a grey box with my title "zachs game appears and thats it.... please help if you know the problem 1 -thank you
package swing9;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class JavaApplication2 extends JFrame implements Runnable {
int x, y, xDirection, yDirection;
Font font = new Font("Arial", Font.BOLD | Font.ITALIC, 30);
public void run() {
try {
while (true) {
move();
Thread.sleep(5);
}
} catch (Exception e) {
System.out.println("Error");
}
}
public void move() {
x += xDirection;
y += yDirection;
if (x <= 0)
x = 0;
if (x >= 300)
x = 300;
if (y <= 50)
y = 50;
if (y <= 300)
y = 300;
}
public void seyXDir(int xdir) {
xDirection = xdir;
}
public void setYDirection(int ydir) {
yDirection = ydir;
}
public class AL extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
int setXDirection = -1;
}
if (keyCode == e.VK_RIGHT) {
int setXDirection = +1;
}
if (keyCode == e.VK_UP) {
int setYDirection = -1;
}
if (keyCode == e.VK_DOWN) {
int setYDirection = +1;
}
}
}
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
int setXDirection = 0;
}
if (keyCode == e.VK_RIGHT) {
int setXDirecetion = 0;
}
if (keyCode == e.VK_UP) {
int setYDirectiom = 0;
}
if (keyCode == e.VK_DOWN) {
int setYDirecction = 0;
}
}
public JavaApplication2() {
addKeyListener((KeyListener) new JavaApplication2.AL());
setTitle("Zachs Game");
setSize(300, 300);
setResizable(false);
setVisible(true);
setBackground(Color.blue);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x = 150;
y = 150;
}
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.drawString("Play", 40, 40);
g.setFont(font);
g.setColor(Color.red);
g.fillOval(x, y, 15, 15);
repaint();
}
public static void main(String[] args) {
new JavaApplication2();
// threads
Thread t1 = new Thread();
t1.start();
}
}
JFrame or any of its super classes do not implement the paintComponent method so is never invoked. Check this yourself by adding the #Override annotation.
Move this method to a new class that extends JComponent and invoke super.paintComponent(g) as the first statement.
Don't call repaint from within paintComponent, this create an infinite loop and degrades performance. Swing Timers were designed to interact more easily with swing components. Use these over than raw Threads for periodic updates.
Aside: JFrame is not focusable by default so KeyEvents which require focus will not be triggered without making the window focusable. Use Key Bindings instead.

Categories

Resources