我正在制作一个游戏,你正在控制一个正方形,物体将在随机的地方产生,你必须拿起来获得积分,同时还必须躲避从一边到另一边的大方块。现在我有2个类(一个用于敌人 - 大方块 - 和一个用于英雄),我还没有使用产卵对象完成点系统,但这不是我现在要做的。
所以我现在的问题是,当你用英雄触碰“敌人”时,我真的不知道如何让这个人输掉游戏/生命。我会知道如何在没有课程的情况下这样做,但我想知道如何在不同的课程中这样做。
如果有人可以解释代码和评论如何做到这一点,它会帮助我很多:)(我读了一些关于类的'扩展',但我不确定这是否是我应该使用的或不是)。
这是我的游戏目前的样子截图,只是为了更好地说明它:
这是主要代码页:
Hero myHero = new Hero(400,480,5);
Enemies myEnemies = new Enemies(50,50,10);
Enemies myEnemies2 = new Enemies(50,350,15);
Enemies myEnemies3 = new Enemies(50,650,12);
void setup() {
size(900,800);
frameRate(30);
smooth();
}
void draw() {
background(0);
myHero.keyPressed();
myEnemies.enemyDisplay();
myEnemies.enemyMove();
myEnemies2.enemyDisplay();
myEnemies2.enemyMove();
myEnemies3.enemyDisplay();
myEnemies3.enemyMove();
}
第1课:
class Enemies {
float xpos, ypos, speed;
Enemies(float x, float y, float s) {
xpos = x;
ypos = y;
speed = s;
}
void enemyDisplay() {
rect(xpos, ypos, 100, 100);
}
void enemyMove() {
xpos += speed;
if((xpos > width - 100) || (xpos < 0)) {
speed *= -1;
}
}
}
第2课:
class Hero {
float xpos_, ypos_, speed_;
Hero(float x, float y, float s) {
xpos_ = x;
ypos_ = y;
speed_ = s;
}
void keyPressed() {
if (key == CODED) {
if (keyCode == UP) {
ypos_ -= speed_;
}
if (keyCode == DOWN) {
ypos_ += speed_;
}
if (keyCode == LEFT) {
xpos_ -= speed_;
}
if (keyCode == RIGHT) {
xpos_ += speed_;
}
}
rect(xpos_,ypos_,30,30);
}
}
答案 0 :(得分:1)
我相信你提出的问题涉及基本的碰撞检测和对象交互。
我会先Enemies
一个List
并在setup()
来电期间创建/添加元素:
List<Enemies> enemies = new List<Enemies>();
enemies.add(new Enemies(50,50,10));
这允许您将所有Enemies
存储在一个对象下。因此,您的draw()
方法看起来像:
void draw(){
background(0);
myHero.keyPressed();
for(Enemies enemy : enemies)
{
enemy.enemyDisplay();
enemy.enemyMove();
if (hero.isCollidingWith(enemy)) // collision method defined in the hero object, but you could define it in the Enemies class as well, it doesn't really matter
{
hero.removeHealth(); // method defined in hero that removes health
}
}
}
此方法将在您的某个类中:
public boolean isColliding(Enemies enemy)
{
// check the x and y coordinates of each object
}
我希望这有助于指出你正确的方向。
答案 1 :(得分:0)
你需要弄清楚碰撞检测以及当你的物体相互碰撞时,基本的东西如:
class Enemy
{
//...
public boolean isColliding(Hero hero)
{
//figure out the distance between two objects, if its less than their size, they are colliding..
//...
}
//...
}
然后你需要游戏循环的一部分来检查是否有任何东西与你的英雄,皮卡,墙壁等相撞......
答案 2 :(得分:0)
看来你需要帮助的第一部分是碰撞检测。我给出的简短回答几乎无疑会引导你更多的问题是看看Area类(特别是Area.intersect)。您可能还想查看我为了显示而放置的类。管理区域in this project here
答案 3 :(得分:0)
这里有几个问题涉及应用程序设计和约定。在尝试解决碰撞检测问题之前,应首先解决这些问题。
Enemies
类只代表一个敌人,因此该类的名称应该反映出来。另外,在方法名称前加上&#34;敌人&#34;是多余的,可以删除。其他更改已在下面的修订版中进行了评论。
public class Enemy {
// Instead of hard-coding in the width and height of an enemy, allow the
// instantiating code to specify the enemy's size. This will allow you
// to have different size enemies and prevents you from having "magic numbers"
// in your code.
private float xpos, ypos, width, height, speed;
public Enemy(float x, float y, float s, float w, float h) {
xpos = x;
ypos = y;
width = w;
height = h;
speed = s;
}
/* These getters will be used for collision detection later */
public float getX() {
return xpos;
}
public float getY() {
return ypos;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
// I've changed `display` to `draw` to be consistent with the method name in
// your main `draw` method.
public void draw() {
rect(xpos, ypos, width, height);
}
// This method now accepts a screenWidth parameter so that the enemy can know
// when they've collided with the left or right wall of the screen without
// having to rely on an global variable.
public void move(int screenWidth) {
xpos += speed;
if ((xpos > screenWidth - width) || (xpos < 0)) {
speed *= -1;
}
}
}
我提到了#34;魔术数字&#34;在上面的一条评论中。有关详情,请参阅此wikipedia article。
Hero
类包含具有下划线后缀的属性名称。其范围从非常规到与其他类中的所有其他属性名称不一致。原始的keyPressed()
方法混合了绘图和移动的逻辑。这两件事已经分开,并且方法的名称与Enemy
类的名称相同。
public class Hero {
private float xpos, ypos, width, height, speed;
public Hero(float x, float y, float s, float w, float h) {
xpos = x;
ypos = y;
width = w;
height = h;
speed = s;
}
// Change this method name to draw for consistency with the Enemy class
public void draw() {
// Key press functionality has been moved to the `move` method for consistency
// with the Enemy class.
rect(xpos, ypos, WIDTH, HEIGHT);
}
// This method uses the variables key, keyCoded, UP, DOWN, LEFT, and RIGHT. You
// did not include any import statements with your code, so they may be coming
// from there; however, if they are globals, you should pass them to this method
// as arguments whenever you call it.
public void move() {
// If this condition isn't satisfied, return immediately. This prevents
// unnecessary nesting and work below.
if (key != CODED) {
return;
}
if (keyCode == UP) {
ypos -= speed;
}
// Use `else if` here and below to prevent multiple unnecessary
// comparisons of keyCode.
else if (keyCode == DOWN) {
ypos += speed;
}
else if (keyCode == LEFT) {
xpos -= speed;
}
else if (keyCode == RIGHT) {
xpos += speed;
}
}
public boolean isColliding(Enemy enemy) {
// Collision detection is easy since all of your game entities (the hero and
// the enemies) are all rectangles and axis-aligned (not rotated). You can
// use a method known as "bounding box intersection."
return (Math.abs(enemy.getX() - xpos) * 2 < (enemy.getWidth() + width))
&& (Math.abs(enemy.getY() - ypos) * 2 < (enemy.getHeight() + height));
}
}
有关边界框交叉点的更多信息,请参阅此gamedev stackexchange question。
现在您的课程已经完成,是时候解决您的主要代码了。我们需要更新方法名称,正如@James T建议的那样,你应该制作一个敌人列表,而不是为每个敌人创建一个新的独立对象。这将使您更容易在将来添加或移除敌人,并且能够使用一个代码块处理所有敌人而无需重复自己。
// Use constants to remove magic numbers.
private static final int SCREEN_WIDTH = 900;
private static final int SCREEN_HEIGHT = 800;
private Hero myHero = new Hero(400, 480, 30, 30, 5);
private List<Enemy> enemies = new ArrayList<Enemy>();
void setup() {
size(SCREEN_WIDTH, SCREEN_HEIGHT);
frameRate(30);
smooth();
enemies.add(new Enemy(50, 50, 100, 100, 10));
enemies.add(new Enemy(50, 350, 100, 100, 15));
enemies.add(new Enemy(50, 650, 100, 100, 12));
}
void draw() {
hasCollision = false;
background(0);
// I've changed the order of draw->move to move->draw. If you draw first, then
// move, then detect collisions, it will appear to your user that your hero has
// not yet collided with an enemy even though you act as they have (e.g.: they
// will not see the collision until the next time you draw the scene).
myHero.move();
myHero.draw();
for (Enemy enemy : enemies) {
enemy.move();
enemy.draw(SCREEN_WIDTH);
if (!hasCollision && myHero.isColliding(enemy)) {
hasCollision = true;
}
}
if (hasCollision) {
// Handle enemy collision here
}
}
您会注意到我还为所有内容添加了辅助功能修饰符。虽然在技术上有效地排除它们并使用默认值,但它使您的代码更易于包含它们,因为它更明显。当你第一次出发时,越明显越好。
答案 4 :(得分:0)
感谢你们所有乐于助人的人们,让它工作!
我这样做了:
public boolean isColliding(Enemies h){
float distance = dist(x,y,h.x,h.y);
if(distance<100){
return true;
}else{
return false;
}
}
在我的画中(){我有
if(myHero.isColliding(myEnemies)){
println("You lost!");
}
我有一个非常相似的解决方案&#39;早些时候,但我之所以出现错误的原因是因为我有“Hero h”而不是“Enemies h”中的“如果&#39;功能,所以我忽略了一个非常愚蠢的错误:P