entergame.jsp:
<%@ page language="java" import="mygame.*" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ include file="loginCheck.jsp" %>
<jsp:useBean id="theplayer" class="mygame.GamePlayer" scope="session"/>
<jsp:useBean id="gamehome" class="mygame.GameHome" scope="application" />
<html>
<head>
<title>加入游戏</title>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
</head>
<body>
<%
int roomno = Integer.parseInt(request.getParameter("room"));//房号 int deskno = Integer.parseInt(request.getParameter("desk"));//桌号 int siteno = Integer.parseInt(request.getParameter("site"));//座号 if (theplayer.desk == null)
{//玩家处于空闲状态,还没有坐下加入任何游戏
GameDesk[] desks = gamehome.rooms.get(roomno).getDesks();
if (desks[deskno].siter[siteno]==null) {//第 deskno 桌第 siteno 座位还空着,坐下加入
theplayer.enterGame(desks[deskno],siteno);//坐上第 deskno 桌的第 siteno 位
theplayer.roomno=roomno;//记忆房号 theplayer.deskno=deskno;//记忆桌号 theplayer.siteno=siteno;//记忆座号
//转到游戏(桌)页
response.sendRedirect("gamedesk.jsp?room="+roomno+"&desk="+deskno);
} else
{//第 deskno 桌第 siteno 座位已被占,不可以坐下加入
%>
<script type="text/javascript">
window.alert("第<%=deskno%>桌第<%=siteno%>座位已被抢占!");
window.location="gameroom.jsp?no=<%=roomno%>";//返回游戏房间页 </script>
<%
} } else
{//玩家早已坐下加入某桌游戏, 处于游戏中,不能再加入其他桌 %>
<script type="text/javascript">
window.alert("你已在游戏中,不能再加入其他游戏!");
window.location="gamedesk.jsp?room=<%=theplayer.roomno
%>&desk=<%=theplayer.deskno%>";//转到游戏桌页 </script>
<%
} %>
</body>
</html>
使用<jsp:useBean>指令,引用在 Session 作用范围内的游戏玩家对象,代表现实中的玩家 用户概念。
程序逻辑:如果 theplayer.desk==null,表示玩家没有加入任何桌,从 request 参数中取到 房号、桌号、座位号,如果 desks[deskno].siter[siteno]==null,表示座位还空着,可以坐下加入 游戏,程序调用:
theplayer.enterGame(desks[deskno],siteno);//坐上第 deskno 桌的第 siteno 位
(4)设计退出游戏页 exitgame.jsp:在游戏(牌桌)页 gamedesk.jsp 上,当用户单击“强 退”时,转到退出游戏页 exitgame.jsp,页中通过调用 theplayer.exitGame(),实现“玩家退出 进行中的游戏(桌)”功能。退出后,theplayer.desk 的值变为 null。
exitgame.jsp:
<%@ page language="java" pageEncoding="GBK"%>
<jsp:useBean id="theplayer" class="mygame.GamePlayer" scope="session"/>
<%
//退出游戏(桌),返回游戏大厅页
theplayer.exitGame();
%>
<script type="text/javascript">
<!--
alert("你放弃了本桌游戏,强行退出了");
location ="gamehome.jsp";
//-→
</script>
6.3.4 实现(坐在)游戏牌桌
把游戏的状态信息及行为封装为游戏(牌桌)类 GameDesk,每一个游戏牌桌的作用范围 都是 application 范围。当把玩家对象实例的引用赋给游戏桌的某位置变量时,表示游戏桌的相 应座位被玩家占着。例如,加入游戏时设置:
desks[i].siter[0] = theplayer; //第 i 桌的第 0 座位被玩家占着
在游戏结束时,初始化游戏桌,恢复设置游戏桌的各座位为空。
(1)按 6.2 节及图 6-5 的设计要求,在项目的 src/mygame 下,打开或创建游戏(牌桌)
类 GameDesk,编写游戏(牌桌)类 GameDesk 的实现代码。
GameDesk.jave:
package mygame;
import java.sql.*;
import java.util.*;
public class GameDesk {
public GamePlayer[] siter = new GamePlayer[4];//4 个位置的玩家 public int[] sitestate = new int[4];//4 个位置的状态
public int playercount;//玩家人数
public int currentplay;//轮到的当前出牌者的位置号
public java.util.Date playouttime;//出牌超时计时开始时间 public int playorder;//出牌顺序:1--顺时针,-1--逆时针 public int deskscore;//桌面牌分
public boolean isplaying;//是否打牌状态
public GameDesk() {
init_desk();//初始化游戏桌 }
//初始化游戏桌
public void init_desk() {
playercount=0;//玩家人数
currentplay = 0;//轮到的当前出牌者的位置号 playorder = 1;//出牌顺序:1--顺时针,-1--逆时针 deskscore =0;//桌面牌分
isplaying = false;//是否打牌状态 for(int i=0;i<4;i++){
siter[i]=null;
sitestate[i]=0;//位置状态:0-游戏中,1,2,3,4 表示第几位结束出牌(出局) }
}
//实现出牌规则的方法:出某种牌,游戏状态如何变化
public void playonecard(int cardnum) throws Exception {
int siteno = currentplay;
switch(cardnum) { case 4:
deskscore -=10;//让中央总分减少 10
currentplay = (4+currentplay+playorder)%4;//轮到下家出牌 break;
case 5:
deskscore -=20;//让中央总分减少 20
currentplay = (4+currentplay+playorder)%4;//轮到下家出牌 break;
case 10:
playorder *=-1;//反转出牌顺序
currentplay = (4+currentplay+playorder)%4;//轮到下家出牌 break;
case 11:
currentplay = (4+currentplay+2)%4;//指定对家出牌 break;
case 12:
deskscore =99;//总分立刻变为 99
currentplay = (4+currentplay+playorder)%4;//轮到下家出牌 break;
default: //0,1,2,3,6,7,8,9 deskscore += cardnum;
currentplay = (4+currentplay+playorder)%4;//轮到下家出牌 if (deskscore>99)
{ //当前出牌玩家出局
kickout_theGame(siteno);
deskscore -= cardnum;//恢复桌分 }
break;
}
//如果轮到的位置玩家已出局,顺延到下一家 while(sitestate[currentplay]>0) {
currentplay = (4+currentplay+playorder)%4;//轮到下家出牌 }
playouttime = new java.util.Date();//下一玩家出牌计时开始时间 }
//检查玩家是否足 4 人,够 4 人就发牌,开始游戏 public boolean check_GameIsStart()
{
if (isplaying==false && playercount==4) {//够 4 人就发牌,开始游戏
Random rand = new Random();
for(int i=0;i<4;i++)//4 个玩家
for(int j=0;j<10;j++)//每玩家 10 张牌
siter[i].cards[j]= rand.nextInt(12);//随机生成 0~12 整数 isplaying = true;//游戏开始
}
currentplay = 0;//0 位置开始出牌
playouttime = new java.util.Date();//下一玩家出牌计时开始时间
return isplaying;
}
//检查游戏是否结束
public boolean check_GameIsOver() throws Exception {
if (isplaying==true && playercount==1)//还剩一个玩家 {//游戏结束,记分
Connection conn=dbConnect.getconntion();//连接到数据库
PreparedStatement pstmt=conn.prepareStatement("update userinfo set PlayNum=PlayNum+1,WinNum=WinNum+?,GameScore=GameScore+? where userid=?");
for(int i=0;i<4;i++)//4 个玩家 {
pstmt.setInt(1, sitestate[i]==4?1:0);//赢次数 pstmt.setInt(2,100*(sitestate[i]-2));//得分 pstmt.setString(3,siter[i].UserID);//得分 pstmt.executeUpdate();
}
conn.close();
//玩家离开此游戏牌桌 for(int i=0;i<4;i++){
if (siter[i]!=null && siter[i].desk==this) siter[i].desk=null;
}
init_desk();//初始化游戏桌 }
return !isplaying;
}
//某座位玩家出局
public void kickout_theGame(int siteno) throws Exception {
if (sitestate[siteno]>0) return;//早已出局
//当前玩家出局,设置其座位为第几位出局者
this.sitestate[siteno]= 5-playercount;//sitestate[i]>0:出局 this.playercount -=1;//出牌人数减 1
this.check_GameIsOver();//有人出局,检查游戏是否结束
if (currentplay==siteno)
{ //如果正好是轮到的此玩家出牌,但已出局,所以顺延到下一家 while(this.sitestate[currentplay]>0)
{
currentplay = (4+currentplay+playorder)%4;//轮到下家出牌 }
playouttime = new java.util.Date();//下一玩家出牌计时开始时间 }
} }