首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单人避障太空游戏

单人避障太空游戏
EN

Code Review用户
提问于 2019-09-12 07:15:20
回答 1查看 403关注 0票数 4

我想知道我能做些什么来改进这个游戏的游戏,以及图形。我想使用LWJGL,但是呈现库并不重要。我只需要找出我的代码的改进,以及我可以做的事情,使它看起来更好,发挥更好。

这个想法很简单。别打红球。你和W和S一起行动,你可以包扎两边。你可以收集绿色球体,这有机会让你更快。当你这样做的时候,他们给你更多的时间,在时钟耗尽之前。你也可以收集蓝色的球体,这有机会让你变慢。在收集它们的时候,你可以移除两个随机的球体。

代码语言:javascript
复制
package me.Rigidity.Rue;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Rue extends JFrame {

    private static final long serialVersionUID = 2724959749690039251L;
    public JPanel graphics;
    public KeyListener key;
    public int width = 750, height = 450;
    public String title = "Rue";
    public boolean[] keys;
    public ArrayList<Item> items;
    public Item player;
    public long points;
    public boolean gameover;
    public int counter;
    public int difficulty;
    public long delay;
    public Random random;
    public long highscore = 0;

    public static class Item {

        public int x, y, w, h, s;
        public Color c;

        public Item(Color c, int x, int y, int w, int h, int s) {
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
            this.c = c;
            this.s = s;
        }

        public static boolean collision(Item a, Item b) {
            return a.x + a.w > b.x && a.y + a.h > b.y && a.x < b.x + b.w && a.y < b.y + b.h;
        }

    }
    public void init() {

        gameover = false;
        keys = new boolean[KeyEvent.KEY_LAST];
        player = new Item(Color.WHITE, 16, height / 2 - 24, 24, 24, 2);
        points = 0;
        counter = 0;
        difficulty = 90;
        delay = 1000/120;
        random = new Random((long)(Math.random()*Long.MAX_VALUE));
        items = new ArrayList<>();
        for (int i = 0; i < height / 45; i++) {
            place();
        }

    }

    public void place() {
        int type = (int)(random.nextDouble()*100)+1;
        if (type < 84) {
            barrier();
            return;
        }
        if (type < 92) {
            power();
            return;
        }
        boost();
    }
    public void barrier() {
        items.add(new Item(Color.RED, width + (int)(random.nextDouble() * width * 2), (int)(random.nextDouble() * (height+32))-16, 16, 16, 2));
    }
    public void power() {
        items.add(new Item(Color.BLUE, width + (int)(random.nextDouble() * width * 2), (int)(random.nextDouble() * (height+32))-16, 16, 16, 2));
    }
    public void boost() {
        items.add(new Item(Color.GREEN, width + (int)(random.nextDouble() * width * 2), (int)(random.nextDouble() * (height+32))-16, 16, 16, 2));
    }

    public void tick() {
        if (gameover) {
            if (keys[KeyEvent.VK_SPACE]) {
                init();
            }
            return;
        }
        if (keys[KeyEvent.VK_W]) {
            player.y -= player.s;
        }
        if (keys[KeyEvent.VK_S]) {
            player.y += player.s;
        }
        ArrayList<Item> old = new ArrayList<>();
        for (Item item : items) {
            old.add(item);
        }
        for (Item item : old) {
            item.x -= item.s;
            if (item.x + item.w < 0) {
                items.remove(item);
                place();
            } else {
                //if (false)
                if (Item.collision(player, item)) {
                    if (item.c == Color.RED) {
                        gameover = true;
                    } else if (item.c == Color.BLUE) {
                        items.remove(item);
                        items.remove(0);
                        items.remove(0);
                        if (random.nextDouble() > 0.7) delay++;
                    } else if (item.c == Color.GREEN) {
                        items.remove(item);
                        difficulty += 16;
                        if (random.nextDouble() > 0.7) delay--;
                    }
                }
            }
        }
        if (player.y + player.h < 0) {
            player.y = height - player.h;
        }
        if (player.y > height - player.h) {
            player.y = -player.h;
        }
        counter += Math.ceil((double)points / 3000.0);
        if (counter > difficulty*2) {
            place();
            counter = 0;
            difficulty -= 2;
            if (difficulty < 20) {
                difficulty = 60;
                delay--;
            }
        }
        points++;
        if (points > highscore) {
            highscore = points;
        }
    }
    public void render(Graphics ctx) {
        ctx.setColor(Color.BLACK);
        ctx.fillRect(0, 0, width, height);
        for (Item item : items) {
            ctx.setColor(item.c);
            ctx.fillRect(item.x, item.y, item.w, item.h);
        }
        ctx.setColor(player.c);
        ctx.fillRect(player.x, player.y, player.w, player.h);
        ctx.setFont(ctx.getFont().deriveFont(22.0f));
        ctx.setColor(Color.GREEN);
        ctx.drawString(""+points, width - ctx.getFontMetrics().stringWidth(""+points) - 5, 22);
        ctx.setColor(Color.BLUE);
        ctx.drawString(""+highscore, width/2 - ctx.getFontMetrics().stringWidth(""+highscore)/2, 22);
        ctx.setColor(Color.RED);
        ctx.drawString(""+(difficulty/2), 5, 22);
    }
    public void setup() {
        key = new KeyListener() {
            public void keyTyped(KeyEvent e) {

            }
            public void keyPressed(KeyEvent e) {
                keys[e.getKeyCode()] = true;
            }
            public void keyReleased(KeyEvent e) {
                keys[e.getKeyCode()] = false;
            }
        };
        graphics = new JPanel() {
            private static final long serialVersionUID = -2152573216046911514L;
            public long then = System.currentTimeMillis();
            public long amount = -2000;
            public boolean initialized = false;
            public void paint(Graphics ctx) {
                if (!initialized)init();
                initialized = true;
                ctx.clearRect(0, 0, width, height);
                long now = System.currentTimeMillis();
                long dist = now - then;
                then = now;
                amount += dist;
                if (delay > 1000/90) {
                    delay = 1000/90;
                }
                if (delay < 1000/300) {
                    delay = 1000/300;
                }
                while (amount >= delay) {
                    amount -= delay;
                    tick();
                }
                render(ctx);
                repaint();
            }
        };
    }

    public Rue() {
        game = this;
        game.setVisible(false);
        game.setSize(width, height);
        //game.setExtendedState(JFrame.MAXIMIZED_BOTH); 
        //game.setUndecorated(true);
        game.setResizable(false);
        game.setLocationRelativeTo(null);
        game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        game.setTitle(title);
        setup();
        game.addKeyListener(key);
        game.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent componentEvent) {
                width = game.getWidth();
                height = game.getHeight();
            }
        });
        game.add(graphics);
        game.setVisible(true);
    }

    public static Rue game;
    public static void main(String[] args) {
        new Rue();
    }

}
EN

回答 1

Code Review用户

回答已采纳

发布于 2019-12-21 18:27:38

很酷的游戏。当所有的代码都很容易复制时,我很喜欢代码评审。在本例中,只需复制和粘贴到IDE中,然后按run按钮:-)

项目类

Item IMO应该改名为GameItemMovableGameObject或类似的东西。它也应该是它自己的文件中的一个类,包含私有方法和getter、setter而不是公共属性。

我花了一段时间才意识到s是速度的缩写。我建议不要把名字缩短为一个字符。唯一的例外是xy,因为它们对于x,y坐标是相当标准的。

避免魔术数字/魔术字符串

在顶部,许多常量应该被声明为静态的最终变量。例如:

代码语言:javascript
复制
private static final int PLAYER_WIDTH = 24;

我建议多读一些关于“魔术数字”的书。这个网站或网上有很多关于它的信息。

方法命名

使用有意义的名称,并且是不言自明的。尽量明确地说,不要使用可能涵盖广泛功能的名称。

place没有解释它在做什么。在重新命名其他方法之前,我不知道它在做什么。

power -应该重命名为createPowerUnitAndAddToList。使用这个新的方法名,它准确地描述了该方法正在做什么,我们可以很容易地从读取名称中看出,该方法可以重构为更有用&遵循单一责任原则。我建议将其命名为createPowerUnit,并让该方法返回一个新项:

代码语言:javascript
复制
public Item createPowerUnit() {
    return new Item(Color.BLUE, width + (int)(random.nextDouble() * width * 2), (int)(random.nextDouble() * (height+32))-16, 16, 16, 2);
}
...
items.add(createPowerUnit());

您可能希望创建一个PowerUnit类并扩展Item。这样就可以对不同的单位进行更多的控制。和/或有一个单独的类来创建单元。这样可以使代码更有条理。

使用else-if

看起来,您在避免使用“else”和“else”语句。在必要的时候使用它们。绝对没有必要回避,这样做是错误的。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/228891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档