gpt4 book ai didi

java - 如何在java中缓慢 move 我的子弹?

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

嗨,我正在开发一款战斗机左右 move 并射击的游戏。对于射击部分,我尝试使用 for 循环来减慢速度,用户可以看到子弹。但这还不够。我也用过 sleep 但不是一个好的答案。现在我不知道该怎么办。
这是我的paintComponent 类:

package game;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JPanel;



public class PaintComponent extends JPanel implements KeyListener {
int dx = 200-15;
int dy = 450;
int my = 450;

ArrayList<Bullet> bullets = new ArrayList<>();
public Rectangle2D rec =new Rectangle2D.Double(dx , dy, 30, 10);
Rectangle2D recB = new Rectangle2D.Double(dx+13 , my, 6, 6);

// public Polygon pol = new Polygon
private BufferedImage imageBg, imageFi, imageBu;


public PaintComponent() {
this.addKeyListener(this);
this.setFocusable(true);
this.setBackground(Color.white);

try {
imageBg = ImageIO.read(new File("C:\\Java\\NetbeansProjects\\Game\\bg.jpg"));
imageBu = ImageIO.read(new File("C:\\Java\\NetbeansProjects\\Game\\bul.png"));
imageFi = ImageIO.read(new File("C:\\Java\\NetbeansProjects\\Game\\fi.png"));
} catch (IOException ex) {
System.out.println("No background image is available!");
}
}

public void shoot(){
if(bullets != null){
for(int i=0; i<bullets.size(); i++){
for(int j=0; j<200; j++){
bullets.get(i).setdy(my-j);
}
System.out.println(bullets.get(i).getdy());
}
}
}
public void moveRec(KeyEvent evt){
switch(evt.getKeyCode()){
case KeyEvent.VK_LEFT:
dx -= 5;
rec.setRect(dx, dy, 30, 10);
recB.setRect(dx+13, dy, 6, 6);
repaint();
break;
case KeyEvent.VK_RIGHT:
dx += 5;
rec.setRect(dx, dy, 30, 10);
recB.setRect(dx+13, dy, 6, 6);
repaint();
break;
case KeyEvent.VK_SPACE:
Bullet b = new Bullet(dx, dy);
bullets.add(b);
shoot();
break;

}
}

@Override
public void paintComponent(Graphics grphcs)
{super.paintComponent(grphcs);
Graphics2D gr = (Graphics2D) grphcs;
int X = (int) rec.getCenterX();
int Y = (int) rec.getCenterY();
gr.drawImage(imageBg, 0, 0, null);
gr.drawImage(imageFi, X-50, Y-75, null);
gr.setColor(Color.GRAY);
if(bullets != null){
for(int i=0;i<bullets.size();i++){
gr.drawImage(imageBu, null, bullets.get(i).getdx(), bullets.get(i).getdy());
repaint();
}
}
gr.draw(recB);
}

@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e)
{moveRec(e);}
@Override
public void keyReleased(KeyEvent e)
{}
}

这是我的子弹课:
package game;

public class Bullet {
private int x, y, newy;

public Bullet(int x, int y){
this.x = x;
this.y = y;
}

public int getdy(){
return y;
}
public void setdy(int newy){
y = newy;
}
public int getdx(){
return x;
}
}

最佳答案

我认为减慢循环速度是错误的。您要做的最后一件事是减慢游戏循环或使游戏循环 hibernate 。这将影响游戏中的所有对象。
有多种方法可以解决这个问题:
每个刻度的较小增量
您可以做的最明显的事情之一就是使子弹的增量更小。让我们看看你的 shoot();方法:

  public void shoot(){
if(bullets != null){
for(int i=0; i<bullets.size(); i++){
for(int j=0; j<200; j++){
bullets.get(i).setdy(my-j);
}
System.out.println(bullets.get(i).getdy());
}
}
}
据我了解,您在所有子弹上迭代 200 倍,每个刻度子弹的 y 轴都会改变,使用公式“my - j”或“450 -刻度索引”
为了减慢子弹的速度,您需要将 j 除以某个数字以获得所需的子弹速度。例如:“my - (j/2)”会影响子弹的速度。尝试使用这些变量来获得所需的速度。
添加速度修饰符
很多游戏都需要为每个弹丸设置速度调节器或基本速度。这可能对你有用,我唯一注意到你有点试图模拟速度损失。要实现此结果,您将需要另一个变量。让我们暂时称其为“生存时间”。
所以如果我们修改子弹类,它看起来像这样。请注意,我们还有一个名为 Move(); 的新函数。这将根据变量计算下一步行动。
public class Bullet {
private int x, y, newy;
private speed, ttl; //ttl = time to live

public Bullet(int x, int y, int speed){
this.x = x;
this.y = y;
this.speed= speed;
this.ttl = 250;
}

public int Move()
{
//Do some calculation to perform loss of velocity within a reasonable range. Because these number might be overkill
this.speed -= (ttl / 100);
y += this.speed;
ttl--;
}

public int getdy(){
return y;
}
public void setdy(int newy){
y = newy;
}
public int getdx(){
return x;
}
}
代码现在所做的是它根据生存时间变量计算速度,子弹生命周期越长,它的速度就越低。调整速度变量使您能够更好地控制子弹。而且我自己这么说,拍摄方法看起来更整洁:
public void shoot(){
if(bullets != null){
for(int i=0; i<bullets.size(); i++){
bullets.get(i).Move();
}
}
}
当然还有更多,比如检查速度和生存时间是否没有超出界限之类的,但我认为你足够聪明,可以解决这个问题;)
用计时器运行它
正如 ControlAltDel 所说,您可以实现一个计时器,我不是 java 专家,所以我不会深入探讨这个问题。但这肯定是一种可能性。它只不过是在计时器的刻度函数中实现当前的拍摄方法。当然删除 for i<200 循环。因为它不是很有效。
无论如何
如果我确实有什么错误或误解(甚至是语法错误:))问题,我很抱歉。如果有任何问题我很乐意听到你的消息;)。
请不要说这是未经测试的代码,我只是在这里解释您可以尝试使其按预期工作的事情!
真诚的,
辛达苏。
更新:
一些解释如何更新子弹的。
为了更新子弹,我们需要让它循环运行。因为在这种情况下,主循环也是绘图发生的地方,“paintComponent”方法。油漆组件已经有一个循环来绘制子弹,我们唯一要做的就是添加我们关于 .Move(); 的逻辑。方法。
油漆组件将如下所示(+ i 还修复了选项卡):
@Override
public void paintComponent(Graphics grphcs)
{
super.paintComponent(grphcs);

Graphics2D gr = (Graphics2D) grphcs;
int X = (int) rec.getCenterX();
int Y = (int) rec.getCenterY();

gr.drawImage(imageBg, 0, 0, null);
gr.drawImage(imageFi, X-50, Y-75, null);
gr.setColor(Color.GRAY);

if(bullets != null)
{
for(int i=0;i<bullets.size();i++)
{
//Here is were we loop over the bullet list, lets add the move method
bullets.get(i).Move();

gr.drawImage(imageBu, null, bullets.get(i).getdx(), bullets.get(i).getdy());
repaint();
}
}

gr.draw(recB);
}
添加的东西是“bullets.get(i).Move();”。这现在将运行每一帧。这在理论上可行(inb4 我没有测试这些代码)。假设您使用子弹类的多个实例,每个类都应该封装自己的速度和生存时间变量。
实现这一点将使拍摄方法过时。您可以做的是将与拍摄相关的paintComponent中的代码 move 到拍摄函数中。
关于生存时间变量,我想在代码中再添加一段。这将负责子弹的垃圾收集。从现在开始,他们无限期地生活:
for(int i=0;i<bullets.size();i++)
{
Bullet b = bullets.get(i);
if(b.ttl >= 1)
{
bullets.get(i).Move();
gr.drawImage(imageBu, null, b.getdx(), b.getdy());
}
else
{
//Remove the bullet from the list
//In C# its bullets.Remove(b);
}

repaint();
}
希望这能解决子弹不动的问题。由于子弹没有被摧毁,潜在的性能问题。在之前,我喜欢听到任何问题! ;)

关于java - 如何在java中缓慢 move 我的子弹?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30170735/

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