gpt4 book ai didi

java - 根据键盘输入让我的 Sprite 面向某个方向 - Java 游戏

转载 作者:行者123 更新时间:2023-12-01 13:01:51 25 4
gpt4 key购买 nike

因此,我通过遵循一系列不同的教程,几乎用 java 编写了一个基本游戏 - 问题是我无法弄清楚如何让我的 Sprite 向不同方向移动。这是我的主要代码

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;
}

}

这是我的玩家类别

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;
}
}

我在这个游戏中有两名玩家,但我真的很困惑如何将 Sprite 方向改变 22.5% 到所需的方向,所以如果我按下玩家 1 的向上键,它会将我的车向北旋转 22.5% 等.我有一个 Sprite 表,每个玩家有 16 个 Sprite ,每次角度变化 22.5% 这真的让我很困惑,我不知道如何实现这个,

感谢您抽出时间查看

最佳答案

这是旋转 Sprite 的基本示例

Spinning

这维护的是一个虚拟状态,Player 对象会检查该虚拟状态以确定应如何相应地更改它。这将操作与结果分开,这意味着可以用其他操作替换该操作(向上箭头键),但仍然获得相同的结果。

此示例还使用 key bindings API ,它不会遇到与 KeyListener 相同的焦点相关问题,但这是一个纯粹的 Swing API,与 Canvas 不兼容,但它是一个不错的选择演示;)

真正的魔法发生在字符 paint 方法中......

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);
}

基本上,这会创建一个AffineTransformation,然后将其复合以产生我们需要的结果。也就是说,首先将其 anchor 位置转换为字符 x/y 位置,然后绕字符中心点旋转。因为它已经被翻译了,所以我们可以简单地在 0x0 处绘制字符。这比尝试在虚拟空间中其他地方计算角色旋转 anchor 要容易得多 - 恕我直言

向上向下箭头键可旋转角色。按下时,角色将继续旋转,这是用于演示目的的示例的功能。

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;
}

}

}

}

请记住,这只是用于展示概念的示例;)

关于java - 根据键盘输入让我的 Sprite 面向某个方向 - Java 游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23463174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com