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

来源:互联网 发布:toggle() python 编辑:程序博客网 时间:2024/06/05 17:08

  在上一节课程中,我们学习了在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;}@Overridepublic 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. 

2 0
原创粉丝点击