目录
首先灰常开森在2020年下半年这学期收获了很多知识,自己的意志也得到了锻炼,尤其是在verilog学习中摸爬滚打
Java课大作业消息出来的时候我脑子一片空白,连Hello World都不会输出,让用Java写个小游戏,七八个星期以来老师上课给我们讲的内容我一点也没印象,莫名有种给你一盒擦炮去炸碉堡的感觉哦。
ddl最后那三天,着实难受>_<…。
往事不可追,寒假决定把自己一点点磨出来的东西传上来,供大家参考和指正,谢谢。
游戏规则
球球大作战是一款多玩家在线益智策略类游戏。在这款游戏中,玩家操控一个具有一定初始体积的小球在地图中移动。为了使自己的小球的体积增大,玩家可以规划自己的路线并吃掉沿途上的“微粒”,“微粒”具有一个很小的体积,吃掉微粒后,小球可以增加相应的体积,随着体积不断变大,如果当玩家控制小球的体积在直径上明显大于另一名玩家的小球时,如果玩家成功地使自己的小球将对方小球的超过二分之一体积覆盖,那么判定成功吃掉对方的小球,玩家控制的小球体积随之增加,对方的小球被吃掉,需要恢复初始体积重新开始游戏。
游戏分析
在编写项目前,首先对需要实现的功能进行分析,制作了如下的分析图。
球球大作战主角是小球,所有的球(玩家、敌人、孢子、粒子等等)都可以归为”球“类,这个类应该具有以下信息。
位置信息 | 大小信息 | 运动信息 | 玩家信息 |
---|---|---|---|
横坐标,纵坐标 | 直径,质量 | 速度大小和方向 | ID,颜色,地区,是否存活 |
完成了球类的分析,接下来考虑球类最主要的方法——移动,为了真实还原效果,计划实现背景相对玩家移动,玩家小球相对屏幕静止的效果。首先分析如何实现背景移动,背景移动需要计算出背景图片的作图起点坐标,因为drawImage()方法中的两个参数是相对窗口的横坐标和纵坐标,所以画图起点坐标可以用(0,0)-(windowx,windowy)得到,代码如下。
g.drawImage(img, -windowx, -windowy, (int) (Width), (int) (Height), null);
然后分析非玩家球类的相对运动。思路是将小球的绝对坐标和相对坐标分开处理,绝对坐标是小球在地图中真实的坐标,其横纵坐标可以超出屏幕上正在运行的窗口显示范围,该坐标以实际地图左上角为原点,相对坐标是小球相对程序窗口的坐标,该坐标以程序窗口左上角为原点。
小球在运动时,其绝对坐标发生改变,由此引起相对坐标的变化,因为玩家控制的小球始终位于屏幕中心,而背景是可移动的,这里还需要定义窗口左上角相对实际地图的坐标,小球相对窗口位置可以用小球绝对坐标和窗口坐标作差得到。
主要实现方法
项目中较为关键的是Ball类。
public class Ball {
private double x; //绘制横坐标
private double y; //绘制纵坐标
private double d; //直径
private double real_x; //中心横坐标
private double real_y; //中心纵坐标
private double speed; //速度
private double degree; //角度
private double m; //质量
private String name; //昵称
private boolean alive; //存活
private Color owncolor; //颜色
private BufferedImage flag; //国家国旗
public Ball(double x, double y, double d) {
this.setX(x);
this.setY(y);
this.setD(d);
this.setOwncolor(randomcolor());
this.real_x = x + d / 2;
this.real_y = y + d / 2;
this.alive = true;
}
public Ball(double x, double y, double speed, double degree, double m) {
this.setX(x);
this.setY(y);
this.speed = speed;
this.degree = degree;
this.m = m;
FreshD();
this.alive = true;
}
public Ball(double x, double y, double speed, double degree, double m, String name) {
super();
this.x = x;
this.y = y;
this.speed = speed;
this.degree = degree;
this.m = m;
this.name = name;
this.setOwncolor(randomcolor());
FreshD();
this.alive = true;
}
public BufferedImage getFlag() {
return flag;
}
public void setFlag(BufferedImage flag) {
this.flag = flag;
}
public boolean isAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getDegree() {
return degree;
}
public void setDegree(double degree) {
this.degree = degree;
}
public double getM() {
return m;
}
public void setM(double m) {
this.m = m;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getD() {
return d;
}
public void setD(double d) {
this.d = d;
}
public double getReal_x() {
return real_x;
}
public void setReal_x(double real_x) {
this.real_x = real_x;
}
public double getReal_y() {
return real_y;
}
public void setReal_y