您的位置:首页 > 编程语言 > Java开发

JavaFX战旗类游戏开发 第三课 创建游戏角色

2014-07-28 17:07 162 查看
  在上一节课程中,我们学习了在JavaFX中绘制游戏地图。这一节课,我们将会创建我们的游戏角色。

  首先,同样的,我们创建一个简单的基类。

  import javafx.scene.canvas.GraphicsContext;

/**
* 游戏物体基类
* @author Wing Mei
*/
public abstract class BaseObject {
protected double x, y;
protected double width,height;
protected boolean isVisible;

public abstract void draw(GraphicsContext gContext);
public abstract void update();

public void moveX(double x){
setX(getX() + x);
}

public void moveY(double y){
setY(getY() + y);
}

public void move(double x,double y){
moveX(x);
moveY(y);
}

public void setLocation(double x,double y){
setX(x);
setY(y);
}

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 getWidth() {
return width;
}

public void setWidth(double width) {
this.width = width;
}

public double getHeight() {
return height;
}

public void setHeight(double height) {
this.height = height;
}

public boolean isCollisionWith(double x,double y){
if(x > getX() && y > getY() && x < getX() + getWidth() && y < getY() + getHeight()){
return true;
}
return false;
}
public boolean isVisible() {
return isVisible;
}
public void setVisible(boolean isVisible) {
this.isVisible = isVisible;
}
}  
  注意了,通常JavaFX中的类的变量,最好采用JavaFX的Property(javafx.bean.property),在后期很多处理上通过绑定机制会很方便,在我本人的JavaFX游戏开发库中都是采用的这个机制。不过在这里,由于赶工,并未使用。只是在此说明一下。

  基类中,只是基本的坐标,大小的属性和基本的碰撞函数。

  下面看看我们的角色类:

import java.util.List;
import java.util.Random;

import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;

public class BasePlayer extends BaseObject {
//角色分组 玩家 敌人 中立(暂未用到)
public enum Group {
Player, Enemy, Normal
}
private String name = "默认";
private int lv = 1;
private int attack = 3;
private int defense = 1;
private int hp = 6;
private int hp_max = 6;
private int exp = 0;
private int gold = 1;
private int move = 4;
private Random random = new Random();
private Image image;
private Group group = Group.Player;
//是否被选择
private boolean isChoose = false;
//是否正在等待攻击(已显示攻击范围)
private boolean isWaitToAttack = false;
//是否正在等待移动(已显示移动范围)
private boolean isWaitToMove = false;
//是否能够行动
private boolean isCanAction = true;
//是否能够移动
private boolean isCanMove = true;
//是否能够攻击
private boolean isCanAttack = true;
//下面是被攻击后的属性(本想做成闪烁,后来图简单没搞,名称未改)
private int flashCount = 10;
private int startCount = 0;
private boolean isFlash = false;

/**
* 等级提升
*/
public void levelUp() {
attack += random.nextInt(3);
defense += random.nextInt(2);
hp += random.nextInt(3);
lv++;
}

/**
* 获取经验证
* @param ex 经验值
*/
public void getExp(int ex){
exp += ex;
if(exp >= 100){
levelUp();
exp = 0;
}
}

/**
* 攻击
* @param player 被攻击的角色
*/
public void attack(BasePlayer player) {
player.hp -= Math.max(0, attack - player.defense);
}

public void draw(GraphicsContext gc) {
gc.save();
if (image != null) {
if (isCanAction) { //如果行动未结束
if (isFlash) { //如果被攻击,绘制红色填充矩形,并等待计数结束
if (startCount < flashCount) {
gc.setGlobalAlpha(0.3f);
gc.setFill(Color.RED);
gc.fillRect(getX(), getY(), width, height);
startCount ++ ;
} else {
startCount = 0;
isFlash = false;
}
}
gc.setGlobalAlpha(1.0f);
gc.drawImage(image, x, y);
} else { //行动结束 透明度变为0.5
gc.setGlobalAlpha(0.5f);
gc.drawImage(image, x, y);
}
gc.setGlobalAlpha(1.5f);
if (isChoose) { // 当被选择时,显示边框
gc.strokeRect(x, y, 32, 32);
}
}
gc.restore();
}

/*
* 被攻击 效果
*/
public void flash() {
isFlash = true;
startCount = 0;
}

/**
* 是否附近有Players里的角色
*
* @param players
* 角色集合
* @return 是否附近有Players里的角色
*/
public boolean isHasNearBP(List<BasePlayer> players) {
int mx = (int) (getX() / width);
int my = (int) (getY() / height);
for (BasePlayer bp : players) {
int x = (int) (bp.getX() / width);
int y = (int) (bp.getY() / height);
if ((x == mx && y == my + 1) || (x == mx - 1 && y == my) || (x == mx + 1 && y == my)
|| (x == mx && y == my - 1)) {
return true;
}
}
return false;
}

/**
* 寻找离自己最近的角色
*
* @param players
* 角色集合
* @return 最近的角色
*/
public BasePlayer getNearestBP(List<BasePlayer> players) {
BasePlayer basePlayer = players.get(0);
for (int i = 0; i < players.size(); i++) {
BasePlayer player = players.get(i);
if (Math.abs(getX() - basePlayer.getX()) + Math.abs(getY() - basePlayer.getY()) > Math.abs(getX()
- player.getX())
+ Math.abs(getY() - player.getY())) {
basePlayer = player;
}
}
return basePlayer;
}

@Override
public void update() {

}

/**
* 重置所有状态
*/
public void reset() {
isChoose = false;
isWaitToAttack = false;
isWaitToMove = false;
isCanAction = true;
isCanMove = true;
isCanAttack = true;
}

/**
* 判断是否与某个点碰撞
*/
public boolean isCollisionWith(double x, double y) {
if (x > getX() && y > getY() && x < getX() + getWidth() && y < getY() + getHeight()) {
return true;
}
return false;
}

public int getLv() {
return lv;
}

public void setLv(int lv) {
this.lv = lv;
}

public int getAttack() {
return attack;
}

public void setAttack(int attack) {
this.attack = attack;
}

public int getDefense() {
return defense;
}

public void setDefense(int defense) {
this.defense = defense;
}

public int getHp() {
return hp;
}

public void setHp(int hp) {
this.hp = hp;
}

public int getExp() {
return exp;
}

public void setExp(int exp) {
this.exp = exp;
}

public int getGold() {
return gold;
}

public void setGold(int gold) {
this.gold = gold;
}

public Image getImage() {
return image;
}

public void setImage(Image image) {
this.image = image;
setWidth(image.getWidth());
setHeight(image.getHeight());
}

public boolean isChoose() {
return isChoose;
}

public void setChoose(boolean isChoose) {
this.isChoose = isChoose;
}

public int getMove() {
return move;
}

public void setMove(int move) {
this.move = move;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public boolean isWaitToAttack() {
return isWaitToAttack;
}

public void setWaitToAttack(boolean isWaitToAttack) {
this.isWaitToAttack = isWaitToAttack;
}

public boolean isWaitToMove() {
return isWaitToMove;
}

public void setWaitToMove(boolean isWaitToMove) {
this.isWaitToMove = isWaitToMove;
}

public Group getGroup() {
return group;
}

public void setGroup(Group group) {
this.group = group;
}

public boolean isCanAction() {
return isCanAction;
}

public void setCanAction(boolean isCanAction) {
this.isCanAction = isCanAction;
}

public boolean isCanMove() {
return isCanMove;
}

public void setCanMove(boolean isCanMove) {
this.isCanMove = isCanMove;
}

public boolean isCanAttack() {
return isCanAttack;
}

public void setCanAttack(boolean isCanAttack) {
this.isCanAttack = isCanAttack;
}

public boolean isFlash() {
return isFlash;
}

public void setFlash(boolean isFlash) {
this.isFlash = isFlash;
}

public int getHpMax() {
return hp_max;
}

public void setHpMax(int hp_max) {
this.hp_max = hp_max;
}
}
  在我的角色类中,定义了基本游戏角色的基本属性,名称,等级,攻击力,防御力,HP,经验值,金钱,移动力等。有一些暂时没有用到,不过没关系,都有注释。
  另外定义几个方法,等级上升,获取经验值,攻击敌人,判断周边四个是否有角色(用于攻击判断),获取最近的角色(用于敌方移动目标确定)。

  下面开始添加我们的角色了:

  在Canvas的定义里增加我方角色和敌方角色的列表。

// 我方角色
private List<BasePlayer> players = new ArrayList<>();
// 敌方角色
private List<BasePlayer> enemys = new ArrayList<BasePlayer>();
  初始化我方角色和敌人角色:

/**
* 初始化我方角色
*/
private void initPlayers() {
Image player1Image = new Image(getClass().getResourceAsStream("player1.png"));
BasePlayer player1 = new BasePlayer();
player1.setName("茉妍");
player1.setImage(player1Image);
player1.setLocation(10 * tileWidth, 8 * tileHeight);

Image player2Image = new Image(getClass().getResourceAsStream("player2.png"));
BasePlayer player2 = new BasePlayer();
player2.setName("张达");
player2.setImage(player2Image);
player2.setLocation(12 * tileWidth, 8 * tileHeight);

Image player3Image = new Image(getClass().getResourceAsStream("player3.png"));
BasePlayer player3 = new BasePlayer();
player3.setName("燕鱈");
player3.setImage(player3Image);
player3.setLocation(8 * tileWidth, 8 * tileHeight);

players.add(player1);
players.add(player2);
players.add(player3);
}

/**
* 初始化敌方角色
*/
private void initEnemy() {
Image orc = new Image(getClass().getResourceAsStream("enemy1.png"));
int[][] locations = { { 3, 3 }, { 3, 5 }, { 5, 3 } };
for (int i = 0; i < 3; i++) {
BasePlayer enemy = new BasePlayer();
enemy.setImage(orc);
enemy.setName("信(克隆)");
enemy.setAttack(3);
enemy.setDefense(1);
enemy.setHp(5);
enemy.setHpMax(5);
enemy.setGroup(Group.Enemy);
enemy.setMove(3);
enemy.setExp(50);
enemy.setLocation(locations[i][0] * tileWidth, locations[i][1] * tileHeight);
enemys.add(enemy);
}
}
  注意这两个初始化方法要放入构造函数。另外,角色的Group分类一定要明确。
  还有图片资源放入Src下和java文件的同级目录中。

  接着开始绘制:

/**
* 绘制角色
*/
public void drawPlayer() {
for (BasePlayer player : players) {
player.draw(gContext);
}
for (BasePlayer enemy : enemys) {
enemy.draw(gContext);
}
}  drawPlayer方法同样的在draw方法中调用。
  这样以来,我们的角色和敌方角色也都创建完成了。

  下面是效果图:

  


  这样,我们的角色就创建完成了。

  这一节课也到此结束了,下一节课,我们将会创建我们的行动菜单,属性菜单等。

 
本文章为个人原创,版权所有,转载请注明出处:http://blog.csdn.net/ml3947。另外我的个人博客:http://www.wjfxgame.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JavaFX 游戏开发 战旗
相关文章推荐