[英]Incredibly Simple Java Game Task Using OOP
So I have been trying to get into making very simple games in Java. 因此,我一直在尝试着用Java开发非常简单的游戏。 I have been having success when I make the entire program in one class, but whenever I try to add object oriented principles everything falls apart. 当我在一堂课中编写整个程序时,我一直很成功,但是每当我尝试添加面向对象的原理时,一切都会崩溃。 What I want is for a bullet to launch from my good guy, which is more or less a turret. 我想要的是从我的好人身上发射一颗子弹,它或多或少是炮塔。 I can set up something like this with ease, but when I try to do so using classes to represent the good guy and the bullet everything falls apart. 我可以很容易地设置类似的东西,但是当我尝试使用类来表示好人和子弹时,一切都会崩溃。 Here is what I have so far. 这是我到目前为止所拥有的。 Sets up the main program frame: 设置主程序框架:
import javax.swing.JFrame;
public class Shooter
{
public static void main (String[] args)
{
JFrame frame = new JFrame("Car");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ShooterPanel panel = new ShooterPanel();
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
ShooterPanel class: ShooterPanel类:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ShooterPanel extends JPanel
{
final int WIDTH = 200, HEIGHT = 100;
GoodGuy hero;
public ShooterPanel()
{
hero = new GoodGuy(0, HEIGHT-20, 20);
addKeyListener(new MoveListener());
setPreferredSize(new Dimension (WIDTH, HEIGHT));
setFocusable(true);
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
hero.draw(page);
}
private class MoveListener implements KeyListener
{
public void keyPressed (KeyEvent event)
{
switch (event.getKeyCode())
{
case KeyEvent.VK_SPACE:
hero.shoot();
break;
}
}
//--------------------------------------------------------------
//Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void keyTyped (KeyEvent event) {}
public void keyReleased (KeyEvent event) {}
}
}
Our protagonist: 我们的主角:
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class GoodGuy
{
private int x, y, size;
private Bullet bullet;
public GoodGuy(int x, int y, int height)
{
size = height;
this.x = x;
this.y = y;
}
public int getSize()
{
return size;
}
public void draw(Graphics page)
{
page.drawRect(x, y, size, size);
}
public void shoot()
{
bullet = new Bullet(x+size, y);
}
}
And his bullet: 还有他的子弹:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Bullet
{
private int x, y;
final int LENGTH = 5, DELAY =200;
private Timer timer;
Graphics page1;
public Bullet(int x, int y)
{
this.x = x;
this.y = y;
timer = new Timer(DELAY, new BulletListener());
timer.start();
}
public void draw(Graphics page)
{
page.drawLine (x, y, x+LENGTH, y);
}
//*****************************************************************
// Represents the action listener for the timer.
//*****************************************************************
private class BulletListener implements ActionListener
{
public void actionPerformed (ActionEvent event)
{
x +=5;
draw(page1);
}
}
}
What I would like to happen is for the space bar to be pressed, a bullet to appear by the good guy, and for it to move across the screen to the right. 我想发生的是按下空格键,好人出现一颗子弹,然后在屏幕上向右移动。 I can't get the bullet to draw at all. 我根本没办法画出子弹。 I have tried several things, all to no avail. 我尝试了几件事,但都无济于事。 I'm sure this is very easy. 我敢肯定这很容易。 As I've said I could do this all in my ShooterPanel class using variables to draw the bullet rather than creating objects, but I want to go object-oriented. 就像我说过的,我可以在ShooterPanel类中使用变量绘制项目符号而不是创建对象来完成所有这些工作,但是我想面向对象。 Does anyone have a solution for me? 有人对我有解决方案吗? I would greatly appreciate some help, but am looking for a solution. 我将不胜感激一些帮助,但正在寻找解决方案。 Please, if you are just going to give a vague suggestion I would prefer no response. 拜托,如果您只是要提出一个模糊的建议,我希望不予回应。 EDIT: Here's how I want my program to work: 编辑:这就是我希望我的程序工作的方式:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class ShooterPanel extends JPanel
{
final int WIDTH = 200, HEIGHT = 100;
GoodGuy hero;
ArrayList<BadGuy> enemies = new ArrayList<BadGuy>();
ArrayList<Bullet> bullets = new ArrayList<Bullet>();
private Timer timer, bulletTimer;
final int DELAY = 200;
int count=0;
private boolean bulletOut = false;
public ShooterPanel()
{
hero = new GoodGuy(0, HEIGHT-20, 20);
addKeyListener(new MoveListener());
timer = new Timer(DELAY, new EnemyListener());
bulletTimer = new Timer(100, new BulletListener());
setPreferredSize(new Dimension (WIDTH, HEIGHT));
//enemies.add(new BadGuy(WIDTH-10, HEIGHT-10));
setFocusable(true );
timer.start();
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
hero.draw(page);
for (int i = 0; i < enemies.size(); i++)
{
enemies.get(i).draw(page);
}
if (bulletOut)
for(Bullet bullet: bullets)
bullet.draw(page);
}
private class MoveListener implements KeyListener
{
//--------------------------------------------------------------
//Responds to the user pressing arrow keys by adjusting the
//image and image location accordingly.
//--------------------------------------------------------------
public void keyPressed (KeyEvent event)
{
switch (event.getKeyCode())
{
case KeyEvent.VK_SPACE:
bullets.add(new Bullet(20,95));
bulletOut = true;
bulletTimer.start();
break;
}
}
//--------------------------------------------------------------
//Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void keyTyped (KeyEvent event) {}
public void keyReleased (KeyEvent event) {}
}
//*****************************************************************
// Represents the action listener for the timer.
//*****************************************************************
private class EnemyListener implements ActionListener
{
//--------------------------------------------------------------
// Updates the position of the image and possibly the direction
// of movement whenever the timer fires an action event.
//--------------------------------------------------------------
public void actionPerformed (ActionEvent event)
{
if (count%20==0)
enemies.add(new BadGuy(WIDTH-10, HEIGHT-10));
for (BadGuy enemy: enemies)
{
enemy.move();
}
count++;
repaint();
}
}
private class BulletListener implements ActionListener
{
//--------------------------------------------------------------
// Updates the position of the image and possibly the direction
// of movement whenever the timer fires an action event.
//--------------------------------------------------------------
public void actionPerformed (ActionEvent event)
{
for(Bullet bullet: bullets)
bullet.move();
for(int i = 0; i < bullets.size(); i++)
{
if (enemies.size() != 0)
{
if (bullets.get(i).getX() > enemies.get(0).getX())
{
bullets.remove(i);
enemies.remove(0);
}
}
if (bullets.size() != 0)
{
if (bullets.get(i).getX()>WIDTH)
bullets.remove(i);
}
}
repaint();
}
}
}
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class GoodGuy
{
private int x, y, size;
private Bullet bullet;
public GoodGuy(int x, int y, int height)
{
size = height;
this.x = x;
this.y = y;
}
public int getSize()
{
return size;
}
public void draw(Graphics page)
{
page.drawRect(x, y, size, size);
}
public void shoot()
{
bullet = new Bullet(x+size, y);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BadGuy
{
private int x, y;
final int RADIUS = 5;
public BadGuy(int x, int y)
{
this.x = x;
this.y = y;
}
public void move()
{
x -= 5;
}
public void draw(Graphics page)
{
page.drawOval(x, y, RADIUS*2, RADIUS*2);
}
public int getX()
{
return x;
}
}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Bullet
{
private int x, y;
final int LENGTH = 5, DELAY =200;
public Bullet(int x, int y)
{
this.x = x;
this.y = y;
}
public void draw(Graphics page)
{
page.drawLine (x, y, x+LENGTH, y);
}
public void move()
{
x += 5;
}
public int getX()
{
return x;
}
}
The shooter class remains the same. 射手等级保持不变。 This is what I want the program to do, but it's not precisely how I want it to do it. 这是我希望程序执行的操作,但并不是我希望它执行的操作。 I would prefer if it were more object-oriented, and each class took care of itself. 如果它更面向对象,并且每个类都照顾好自己,我会更愿意。 The ShooterPanel is already starting to get a little convoluted for my taste, and only gets worse as more is added to the program. ShooterPanel已经开始对我的口味产生一些困扰,并且只会随着程序的添加而变得更糟。 One thing I would like to change would be for each bullet to have its own timer, with an ActionListener defined in the Bullet class. 我想更改的一件事是使每个项目符号都有自己的计时器,并在Bullet类中定义一个ActionListener。 However, I cannot figure out how to do this in such a way that the bullet is redrawn every time the timer fires an event. 但是,我无法弄清楚如何以这种方式使计时器每次触发事件时都重新绘制项目符号。 If anyone knows a way to do so, please let me know. 如果有人知道这样做的方法,请告诉我。
You need to make your ShooterPanel focusable. 您需要使ShooterPanel聚焦。 Add: 加:
setFocusable(true);
requestFocusInWindow();
Also the Graphics for BulletListener is never set. 此外,从未设置BulletListener的图形。 This paint(ing) should probably happen in the ShooterPanel itself. 这种绘画可能应该在ShooterPanel本身中发生。
尝试利用KeyBindings API代替KeyListener
,如果设置正确,它将KeyListener
焦点问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.