--startGame类
public class StartGame {
/**
* 启动游戏
* @param args
*/
public static void main(String[] args) {
Game game = new Game(); //创建游戏类
game.start(); //开始游戏
}
}
--Game类
import java.util.*;
public class Game {
Map map; //地图
int playerPos1; //对战中玩家1的当前位置
int playerPos2; //对战中玩家2的当前位置
String[] goAndStop = new String[2]; //走或停标识设置
String[] playerName = new String[2]; //对战角色
/**
* 初始化游戏的一局
*/
public void init(){
map = new Map();
map.createMap(); //生成地图
playerPos1 = 0; //设置玩家1起始位置
playerPos2 = 0; //设置玩家2起始位置
goAndStop[0] = "on"; //记录玩家1下一次走或停
goAndStop[1] = "on"; //设置玩家2下一次走或停
}
/**
* 开始游戏
*/
public void start(){
//初始化
init();
System.out.println("※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※");
System.out.println("// //");
System.out.println("// //");
System.out.println("// 骑 士 飞 行 棋 //");
System.out.println("// //");
System.out.println("// //");
System.out.println("※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
System.out.println("\n~~~~~~~~~~~~~~~~~~~两 人 对 战~~~~~~~~~~~~~~~~~~~");
System.out.println("\n请选择角色: 1. 戴高乐 2. 艾森豪威尔 3. 麦克阿瑟 4. 巴顿");
Scanner input = new Scanner(System.in);
System.out.print("请玩家1选择角色: ");
int role1 = input.nextInt();
int role2;
do{
System.out.print("请玩家2选择角色: ");
role2 = input.nextInt(); //双方选择角色代号
}while(role2==role1); //不允许角色重复
setRole(1, role1); //设置玩家1代表的角色
setRole(2, role2); //设置玩家2代表的角色
play(); //开始两人对战
}
/**
* 设置对战角色
* @param no 玩家次序 1:玩家1 2:玩家2
* @param role 角色代号
*/
public void setRole(int no,int role){
switch(role){
case 1:
playerName[no-1] = "戴高乐";
break;
case 2:
playerName[no-1] = "艾森豪威尔";
break;
case 3:
playerName[no-1] = "麦克阿瑟";
break;
case 4:
playerName[no-1] = "巴顿";
break;
default:
break;
}
}
/**
* 两人对战玩法
*/
public void play(){
System.out.println("\n\n\n\n");
System.out.print("\n\n****************************************************\n");
System.out.print(" Game Start \n");
System.out.print("****************************************************\n\n");
//显示对战双方士兵样式
System.out.println("^_^" + playerName[0] + "的士兵: A");
System.out.println("^_^" + playerName[1] + "的士兵: B\n");
//显示对战地图
System.out.println("\n图例: " + "■ 暂停 ¡è 幸运轮盘 ★ 地雷 〓 时空隧道 ∷ 普通\n");
map.showMap(playerPos1, playerPos2);
//游戏开始
int step; //存储骰子数目
while(playerPos1 < 99 && playerPos2 < 99){ //有任何一方走到终点,跳出循环
//轮流掷骰子
if(goAndStop[0].equals("on")){
//玩家1掷骰子
step = throwShifter(1); //掷骰子
System.out.println("\n-----------------"); //显示结果信息
System.out.println("骰子数: "+ step);
playerPos1 = getCurPos(1, playerPos1, step); //计算这一次移动后的当前位置
System.out.println("\n您当前位置: "+ playerPos1);
System.out.println("对方当前位置:"+ playerPos2);
System.out.println("-----------------\n");
map.showMap(playerPos1, playerPos2); //显示当前地图
if(playerPos1 == 99){ //如果走到终点
break; //退出
}
}else{
System.out.println("\n" + playerName[0] +"停掷一次!\n"); //显示此次暂停信息
goAndStop[0] = "on"; //设置下次可掷状态
}
System.out.println("\n\n\n\n");
if(goAndStop[1].equals("on")){
//玩家2掷骰子
step = throwShifter(2); //掷骰子
System.out.println("\n-----------------"); //显示结果信息
System.out.println("骰子数: "+ step);
playerPos2 = getCurPos(2, playerPos2, step); //计算这一次移动后的当前位置
System.out.println("\n您当前位置: "+ playerPos2);
System.out.println("对方当前位置:"+ playerPos1);
System.out.println("-----------------\n");
map.showMap(playerPos1, playerPos2);
if(playerPos2 == 99){ //如果走到终点
break; //退出
}
}else{
System.out.println("\n" + playerName[1] + "停掷一次!\n"); //显示此次暂停信息
goAndStop[1] = "on"; //设置下次可掷状态
}
System.out.println("\n\n\n\n");
}
//游戏结束
System.out.println("\n\n\n\n");
System.out.print("****************************************************\n");
System.out.print(" Game Over \n");
System.out.print("****************************************************\n\n");
judge();
}
/**
* 掷骰子
* @param no 玩家次序
* @return step 掷出的骰子数目
*/
public int throwShifter(int no){
int step = 0;
System.out.print("\n\n" + playerName[no-1] + ", 请您按任意字母键后回车启动掷骰子: ");
Scanner input = new Scanner(System.in);
String answer = input.next();
step = (int)(Math.random()*10) % 6 + 1; //产生一个1~6的数字,即掷的骰子数目
return step;
}
/**
* 计算玩家此次移动后的当前位置
* @param no 玩家次序
* @param position 移动前位置
* @param step 掷的骰子数目
* @return position 移动后的位置
*/
public int getCurPos(int no,int position,int step){
position = position + step; //第一次移动后的位置
if(position >= 99){
return 99;
}
Scanner input = new Scanner(System.in);
switch(map.map[position]){ //根据地图中的关卡代号进行判断
case 0: //走到普通格
if(no ==1 && playerPos2 == position){ //玩家1与对方骑兵相遇
playerPos2 = 0; //踩到对方,对方回到起点
System.out.println(":-D 哈哈哈哈...踩到了!");
}
if (no == 2 && playerPos1 == position){ //玩家2与对方骑兵相遇
playerPos1 = 0; //踩到对方,对方回到起点
System.out.println(":-D 哈哈哈哈...踩到了!");
}
break;
case 1: //幸运轮盘
System.out.println("\n◆◇◆◇◆欢迎进入幸运轮盘◆◇◆◇◆");
System.out.println(" 请选择一种运气:");
System.out.println(" 1. 交换位置 2. 轰炸");
System.out.println("=============================\n");
int choice = input.nextInt();
int temp;
switch(choice){
case 1:
if(no == 1){
temp = position;
position = playerPos2;
playerPos2 = temp;
}else if(no == 2){
temp = position;
position = playerPos1;
playerPos1 = temp;
}
break;
case 2:
if(no == 1 && playerPos2 < 6){
playerPos2 = 0;
}else{
playerPos2 = playerPos2 - 6;
}
if(no == 2 && playerPos2 < 6){
playerPos1 = 0;
}else{
playerPos1 = playerPos1 - 6;
}
break;
}
//System.out.println(":~) " + "幸福的我都要哭了...");
break;
case 2: //踩到地雷
position = position -6; //踩到地雷退6步
System.out.println("~:-( " + "踩到地雷,气死了...");
break;
case 3: //下一次暂停一次
goAndStop[no-1] = "off"; //设置下次暂停掷骰子
System.out.println("~~>_<~~ 要停战一局了。");
break;
case 4: //时空隧道
position = position + 10; //进入时空隧道,加走10步
System.out.println("|-P " + "进入时空隧道, 真爽!");
break;
}
//返回此次掷骰子后玩家的位置坐标
if(position < 0){
return 0;
}else if(position > 99){
return 99;
}else{
return position;
}
}
/**
* 显示对战结果
*/
public void judge(){
if(playerPos1 > playerPos2){
System.out.println("\n恭喜" + playerName[0] + "将军! 您获胜了!");
}else{
System.out.println("\n恭喜" + playerName[1] + "将军! 您获胜了!");
}
}
}
--Map类
public class Map {
int[] map = new int[100]; //对战地图
int[] luckyTurn = {6, 23, 40, 55, 69, 83}; //幸运轮盘
int[] landMine = {5, 13, 17, 33, 38, 50, 64, 80, 94}; //地雷位置
int[] pause = {9, 27, 60, 93}; //暂停
int[] timeTunnel = {20, 25, 45, 63, 72, 88, 90}; //时空隧道
/**
* 生成地图:
* 关卡代号为:1:幸运轮盘 2:地雷 3: 暂停 4:时空隧道 0:普通
*/
public void createMap(){
int i = 0;
//在对战地图上设置幸运轮盘
for(i = 0; i < luckyTurn.length; i++){
map[luckyTurn[i]] = 1;
}
//在对战地图上设置地雷
for(i = 0; i < landMine.length; i++){
map[landMine[i]] = 2;
}
//在对战地图上设置暂停
for(i = 0; i < pause.length; i++){
map[pause[i]] = 3;
}
//在对战地图上设置时空隧道
for(i = 0; i < timeTunnel.length; i++){
map[timeTunnel[i]] = 4;
}
}
/**
* 显示地图关卡对应的图形
* @param i 地图当前位置的关卡代号
* @param index 当前地图位置编号
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
* @return 地图当前位置的对应图片
*/
public String getGraph(int i,int index,int playerPos1, int playerPos2){
String graph = "";
if(index == playerPos1 && index== playerPos2){
graph = "@@";
}else if(index == playerPos1){
//graph = "♀";
graph = "A";
}else if(index == playerPos2){
//graph = "♂";
graph = "B";
}else{
switch(i){
case 1: //幸运轮盘
graph = "¡è";
break;
case 2: //地雷
graph = "★";
break;
case 3: //暂停
graph = "■";
break;
case 4: //时光隧道
graph = "〓";
break;
default:
graph = "∷";
break;
}
}
return graph;
}
/**
* 输出地图的奇数行(第1、3行)
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showLine1(int start,int end,int playerPos1, int playerPos2){
for(int i = start; i < end; i++){
System.out.print(getGraph(map[i], i, playerPos1, playerPos2));
}
}
/**
* 输出地图的偶数行(第2行)
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showLine2(int start,int end,int playerPos1, int playerPos2){
for(int i = end-1; i >= start; i-- ){
System.out.print(getGraph(map[i], i,playerPos1, playerPos2));
}
}
/**
* 输出地图的右竖列
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showRLine(int start,int end,int playerPos1, int playerPos2){
for(int i = start; i< end; i++){
for(int j = 28; j > 0; j--){ //输出29个空格
System.out.print(" ");
}
System.out.print(getGraph(map[i], i,playerPos1, playerPos2));
System.out.println();
}
}
/**
* 输出地图的左竖列
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showLLine(int start,int end,int playerPos1, int playerPos2){
for(int i = start; i < end; i++){
System.out.println(getGraph(map[i], i,playerPos1, playerPos2));
}
}
/**
* 显示对战地图
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showMap(int playerPos1,int playerPos2){
showLine1(0, 31, playerPos1, playerPos2); //显示地图第一行
System.out.println(); //换行
showRLine(31,35, playerPos1, playerPos2); //显示地图右竖行
showLine2(35, 66, playerPos1, playerPos2); //显示地图第二行
System.out.println(); //换行
showLLine(66, 69, playerPos1, playerPos2); //显示地图左竖行
showLine2(69, 100, playerPos1, playerPos2); //显示地图第3行
}
}
从北大青鸟课件中得到的启发,今天无意中看到了这个小示例,虽然简单,但感觉代码逻辑值得借鉴。
图例: ■ 暂停 ¡è 幸运轮盘 ★ 地雷 〓 时空隧道 ∷ 普通
@@∷∷∷∷★¡è∷∷■∷∷∷★∷∷∷★∷∷〓∷∷¡è∷〓∷■∷∷∷
∷
∷
★
∷
∷★〓∷∷■∷∷∷∷¡è∷∷∷∷★∷∷∷∷〓∷∷∷∷¡è∷★∷∷∷
∷
∷
∷
∷∷∷∷∷★■∷∷〓∷〓∷∷∷∷¡è∷∷★∷∷∷∷∷∷∷〓∷∷¡è
要是自己的话可以先想想,自己如何绘制该图形。
同时,通过该示例得到了一个启发: 就是在做射击类的游戏时,可以先定义好精灵行走的路线,然后根据路线来改变精灵的当前坐标,这样就看起来精灵像是在道路(河流)中行走而不会出来。以下是自己写的一个小示例:
package riverRun;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class RiverRunApp extends Frame {
public static final int MAP_WIDTH = 800;
public static final int MAP_HEIGHT = 600;
private Image offScreenImage = null;
private Map map = null; // 绘制地图
public RiverRunApp() {
map = new Map();
}
public static void main(String[] args) {
RiverRunApp app = new RiverRunApp();
app.lauchFrame();
}
/** 初始化窗体信息 */
private void lauchFrame() {
this.setTitle("精灵沿指定路线行走");
this.setSize(MAP_WIDTH, MAP_HEIGHT);
this.setResizable(false); // 是否可以调整大小
this.setBackground(new Color(187, 201, 229));
this.setVisible(true);
this.setLocation(800, 500);
new Thread(new ThreadPaint()).start();
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
/** 重绘屏幕 */
class ThreadPaint implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(41);
repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void paint(Graphics g) {
map.draw(g);
}
/** 加入缓冲区 */
public void update(Graphics g) {
if (offScreenImage == null) {
offScreenImage = this.createImage(MAP_WIDTH, MAP_HEIGHT);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(new Color(187, 201, 229));
gOffScreen.fillRect(0, 0, MAP_WIDTH, MAP_HEIGHT);
gOffScreen.setColor(c);
this.paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}
}
==========================
package riverRun;
import java.awt.Graphics;
/**
* 显示抽象类
*/
public abstract class ShowEntity {
/**绘制抽象方法*/
protected abstract void draw(Graphics g);
}
===================================
package riverRun;
import java.awt.Color;
import java.awt.Graphics;
/**
* 地图类
*/
public class Map {
public static final int row = RiverRunApp.MAP_HEIGHT / Grid.GRID_HEIGHT;
public static final int cell = RiverRunApp.MAP_WIDTH / Grid.GRID_WIDTH;
private ShowEntity hero = null;
private ShowEntity grid = null;
private int[][] maps = new int[row][cell]; //地图网格
//河流行走的路线
private int[][] riverRoadLine = new int[][]{{3,0},{3,1},{3,2}, {3,3},{3,4},{3,5}, //第一横行
{4,5},{5,5},{6,5}, //右边竖行
{6,4},{6,3},{6,2}, //第二横行
{7,2},{8,2},{9,2},{10,2}, //左边竖行
{11,2},{11,3},{11,4},{11,5},{11,6},{11,7},{11,8},{11,9},{11,10}}; //第三横行
public Map(){
initMapInfo();
hero = new Hero(riverRoadLine);
grid = new Grid();
System.out.println("初始化地图信息");
}
/**初始化地图信息*/
private void initMapInfo() {
for(int i = 0; i < riverRoadLine.length; i++){
for(int j = 0; j < riverRoadLine[0].length; j++){
int m = riverRoadLine[i][0];
int n = riverRoadLine[i][1];
maps[m][n] = 1;
}
}
}
public void draw(Graphics g){
System.out.println("绘制地图");
for(int i = 0; i < row; i++){
for(int j = 0; j < cell; j++){
switch(maps[i][j]){
case 0: //土地
g.setColor(Color.RED);
break;
case 1: //河流
g.setColor(Color.GREEN);
break;
}
g.fill3DRect(j * Grid.GRID_WIDTH, i * Grid.GRID_HEIGHT, Grid.GRID_WIDTH, Grid.GRID_HEIGHT, false);
}
}
grid.draw(g);
hero.draw(g);
}
}
==========================================
package riverRun;
import java.awt.Graphics;
/**
* 格子
*/
public class Grid extends ShowEntity{
public static final int GRID_WIDTH = 40; //宽度
public static final int GRID_HEIGHT = 40; //高度
public Grid(){
System.out.println("初始化格子构造方法");
}
@Override
protected void draw(Graphics g) {
System.out.println("绘制格子");
}
}
============================================
package riverRun;
import java.awt.Color;
import java.awt.Graphics;
/**
* 行走的精灵
*/
public class Hero extends ShowEntity{
private int[][] roadline; //行走的路线
private int x; //当前X坐标
private int y; //当前Y坐标
private int aimX; //目标点X
private int aimY; //目标点Y
private int width; //宽度
private int height; //高度
private int speed; //速度
private int curGrid = 0; //行走到的当前格子
public Hero(int[][] riverRoadLine){
System.out.println("初始化精灵构造方法");
this.roadline = riverRoadLine;
x = roadline[curGrid][1] * Grid.GRID_WIDTH + (Grid.GRID_WIDTH >> 1) - (width >> 1);
y = roadline[curGrid][0] * Grid.GRID_HEIGHT + (Grid.GRID_HEIGHT >> 1) - (height >> 1);
++curGrid;
aimX = roadline[curGrid][1] * Grid.GRID_WIDTH + (Grid.GRID_WIDTH >> 1);
aimY = roadline[curGrid][0] * Grid.GRID_HEIGHT + (Grid.GRID_HEIGHT >> 1);
width = 20;
height = 20;
speed = 4;
}
@Override
protected void draw(Graphics g) {
System.out.println("绘制精灵");
g.setColor(Color.BLUE);
g.fillOval(x, y, width, height);
move();
}
/**
* 精灵行走
*/
public void move(){
if(curGrid >= roadline.length){
System.out.println("精灵到达了目的地");
return;
}else{
System.out.println("精灵的行走");
}
double spaceX = aimX - x;
double spaceY = aimY - y;
double angle = Math.atan2(spaceY, spaceX);
double fx = Math.cos(angle) * speed;
double fy = Math.sin(angle) * speed;
if((aimX - x) * (aimX - x) + (aimY - y) * (aimY - y) < speed * speed){
//取下一个目标点
++curGrid;
aimX = roadline[curGrid][1] * Grid.GRID_WIDTH + (Grid.GRID_WIDTH >> 1);
aimY = roadline[curGrid][0] * Grid.GRID_HEIGHT + (Grid.GRID_HEIGHT >> 1);
}else{
x += fx;
y += fy;
}
}
}