java程序运行网页游戏

0

在Java中,你可以通过使用Java Swing或JavaFX库来开发和运行网页游戏。这种方法被称为"Web Browser Control"或者"Web View",它允许Java应用程序在本地浏览器中显示网页内容,包括运行网页游戏。

以下是一个简单的例子,使用Java Swing的JWebView组件:

```java import javax.swing.*; import java.awt.*;

public class WebGameRunner { public static void main(String[] args) { try { JDesktopPane desktop = new JDesktopPane(); desktop.setAlwaysOnTop(true); desktop.add(new JInternalFrame("Web Game", true, true, true, true) { private JWebView browser;

@Override public void addNotify() { super.addNotify(); browser = new JWebView(); browser.setBounds(10, 10, 800, 600); getContentPane().add(browser); browser.setUrl("http://example.com/your_game_url"); // replace with your game's URL } }); JFrame frame = new JFrame("Web Game Runner"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(desktop); frame.setSize(850, 650); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } } ```

在这个例子中,我们创建了一个JDesktopPane,然后在其内部添加了一个JInternalFrame,这个内部框架中包含了一个JWebView组件。然后我们设置了游戏的URL,这样游戏就在JWebView中运行了。

请注意,这种方法可能不适用于所有类型的网页游戏,因为某些游戏可能需要特定的浏览器环境或API支持。对于这些游戏,你可能需要使用专门的HTML5游戏引擎(如Phaser, Pixi.js等)或者使用WebRTC等技术来实现。

Java在游戏服务器开发中的应用

充值是游戏收入的唯一方式,所以这个功能必须流畅,毫无压力。如果由于网络或服务器性能原因,导致玩家充值不了,会直接影响收益的。所以充值服务器最好部署在一台单独的物理机上面,也可以多个分区使用一个充值服务器,这要视游戏人数而定。

现在很多游戏都对用户进行了集中管理。这方便了对用户提供更好的服务,比如充值、活动、礼包领取、新游戏导入用户等。有的游戏公司可能会用用户中心的数据发展游戏运营平台。这部分与游戏逻辑服务器分开,也减少了游戏逻辑服务器的压力。用户中心采用JavaWeb开发,它对游戏服务器只提供特定访问的接口,把数据与逻辑分离开来,方便管理,以及分布式部署,增强了架构的灵活性。

对玩家的操作进行逻辑处理。逻辑服务器是整个游戏的心脏。它的工作效率直接影响玩家在游戏中的体验,所以对它的要求就是速度,快速返回处理结果。为了达到满足要求的速度,逻辑服务器的大部分操作必须在内存中操作,避免I/O操作,I/O操作可以放到另外的线程中进行。说是大部分,是因为玩家在第一次登录的时候可能会从数据库加载所要用到的数据。在图中,大家看到了缓存,缓存的作用就是把数据放在内存中。当玩家退出时,它的数据也会在缓存中保存一段时间,在一定时间内,玩家再次登录,将不会再重新从数据库加载数据。在逻辑服务器中对数据库的操作可以先放入一个Java队列中,再另起一个Java线程负责从这个队列取数据,并发送到数据库服务器,这就是使用Java的阻塞队列,快速实现一个生产者—消费者模式,数据生产与处理相分离,这样既减轻了逻辑服务器的压力,也保证了数据处理的效率。逻辑服务器的日志也不在逻辑服务器入库,同样的发送到日志服务器处理。还有一种方法是以一种特定格式的方式,记录到本地文件中,再启动一个进程,读取这个文件,然后入库。

java程序运行网页游戏

负责处理玩家登录的请求。一个登录服务器对应多个游戏逻辑分区。当玩家登录的时候,登录服务器向用户中心服务器发送登录信息。请求对登录信息的验证。通过验证之后,返回分区地址lol手游的活动盒子不见了,之后,客户端与登录服务器断开,连接到游戏逻辑服务器。登录服务器是一个单独的Java运行程序,当访问量增加大,可以增加部署到多个物理服务器上面,均衡负载访问压力。它通过使用Java的NIO(非阻塞)方式与客户端进行通信。通过用户中心服务器提供的接口访问用户中心,进行数据处理。

我们公司选择使用Java做服务器开发语言,主要原因是:1.Java是跨平台的,方便部署;2.Java是安全的高级语言,可以提高开发效率;3.Java是面向对象的,代码可以重用;4.Java的分布式应用。

一个完整Java后端js前端棋牌游戏项目源代码,部署运行

煮酒论英雄——评述网页游戏的梦起功成

网页游戏的灵魂在于创意,网页游戏的成功与家用游戏机的成功之路有异曲同工之处:通常机能最弱的游戏机,往往能诞生好游戏,像3DO这类企图依靠脸蛋打江山的机种没几年就死掉了,反倒是FC、GAMEBOY等一些低性能机种为大家留下了无数的经典大作。

所以,对新兴的网游创业者而言,网页游戏是一个全新的蓝海空间:网络通信细节被浏览器实现了,游戏开发者不需购买昂贵的网络引擎就可廉价地实现网络游戏。对游戏业来说,在中国这样一个盗版横行的环境中,网络游戏是唯一的赢利途径,但传统的PC网游开发成本高,网页游戏的出现,自然为中国游戏业 “年轻”的创业者们提供了一个绝佳的机会。

更为重要的是,投资一款大型客户端网络游戏,即使技术成熟,资金到位,拥有一支有着成功经验的团队制作,投入制作周期也往往在1年之久,而当1年后,产品出现到市场后,是否还适应当时的市场环境还未可知,更何况在开发过程中所将遇到的各种BUG以及服务器要求问题。

同时,更加让所有运营商为之侧目的是——网页游戏比传统网络游戏更具获益空间!众所周知,网页游戏的主流玩家为上班族白领玩家,这个群体恰恰就是网民中有最为具备支付能力的玩家,白领玩家的特点是工作压力大,玩游戏的时间和精力少,但却拥有足够的支付能力,并且舍得为其所看中的网络娱乐方式付费。

更可怕的是,当技术硬伤被抚平之后,网页游戏最大的优势——方便性更加被发挥得肆无忌惮!——不需要下载数据包、不需安装客户端、不需要安装光盘,玩家只需打开网页就可以玩的游戏,从第一步:游戏参与方式上就实现了革命性改变的网页游戏,几乎可以向中国所有网民张开怀抱。

一起来看下,Java在游戏服务器开发中的注意事项!

对玩家的操作进行逻辑处理。逻辑服务器是整个游戏的心脏。它的工作效率直接影响玩家在游戏中的体验,所以对它的要求就是速度,快速返回处理结果。为了达到满足要求的速度,逻辑服务器的大部分操作必须在内存中操作,避免I/O操作,I/O操作可以放到另外的线程中进行。说是大部分,是因为玩家在第一次登录的时候可能会从数据库加载所要用到的数据。在图中,大家看到了缓存,缓存的作用就是把数据放在内存中。当玩家退出时,它的数据也会在缓存中保存一段时间,在一定时间内,玩家再次登录,将不会再重新从数据库加载数据。

负责处理玩家登录的请求。一个登录服务器对应多个游戏逻辑分区。当玩家登录的时候,登录服务器向用户中心服务器发送登录信息。请求对登录信息的验证。通过验证之后,返回分区地址,之后,客户端与登录服务器断开,连接到游戏逻辑服务器。登录服务器是一个单独的Java运行程序,当访问量增加大,可以增加部署到多个物理服务器上面,均衡负载访问压力。它通过使用Java的NIO(非阻塞)方式与客户端进行通信。通过用户中心服务器提供的接口访问用户中心,进行数据处理。

最后隆重致谢本项目的制作者马士兵老师, 除了简单的网络知识, 马老师在项目中不停强调程序设计的重要性, 这也是我今后要努力的方向.

当整个项目做完后, 再次考虑协议这个名词, 能看出它共通的地方, 如果让我设计一个通信协议, 我也不会因对设计协议完全没有概念而彷徨了, 当然设计得好不好就另说咯.

但是协议最终是要执行的, 在本项目中运输层协议可以直接调用Java api实现, 但是应用层协议就要自己定义了. 尽管只是定义了几个超级简单的协议, 但是定义过的协议在发送端和接收端是如何处理的, 是落实到代码敲出来的.

现在我重新考虑协议这个名词, 在网络中, 每一种协议定义了一种端到端的数据传输规则, 从应用层到网络层, 只要有数据传输的地方就需要协议. 人类的智慧在协议中充分体现, 比如提供可靠数据传输和拥塞控制的TCP协议和轻便的UDP协议, 它们各有优点, 在各自的领域作出贡献.

最后回顾整个项目, 整个项目并没有用到什么高新技术, 相反这是一个十多年前用纯Java实现的教学项目. 我觉得项目中的网络部分对我的帮助非常大. 我最近看完了《计算机网络:自顶向下方法》, 甚至把里面的课后复习题都做了一遍, 要我详细描述TCP三次握手, 如何通过DHCP协议获取IP地址, DNS的解析过程都不是问题, 但是总感觉理论与实践之间差了点东西.

但是在本游戏中, 只要坦克的方向一发生移动就会发送一个TankMoveMsg包, TankMoveMsg消息中除了包含坦克的方向, 也包含坦克的坐标, 相当于做了客户端线程同步. 所以考虑暂时不需要再额外进行客户端同步了.

在完成基础版本后考虑过这个问题, 因为在游戏中, 由于延时的原因, 可能会造成各个客户端线程不同步. 处理手段可以是每隔一定时间, 各个客户端向服务器发送自己坦克的位置消息, 服务器再将该位置消息通知到其他客户端, 进行同步.

完成这个版本后, 多人游戏时游戏性更强了, 当一个玩家死后他可以重新开启游戏再次加入战场. 但是有个小问题, 他可能会加入到击败他的坦克的阵营, 因为服务器为坦克分配的id好是递增的, 而判定坦克的阵营仅通过id的奇偶判断. 但就这个版本来说服务器端处理死亡坦克的任务算是完成了.

当一辆坦克死后, 服务器应该从Client集合中删除掉该客户端的信息, 从而不用向该客户端发送信息, 减轻负载.而且服务器应该开启一个新的UDP端口号用于接收坦克死亡的消息, 不然这个死亡的消息会转发给其他客户端.

当旧坦克接收TankNewMsg后证明有新坦克加入, 它先把新坦克加入到容器中, 再向服务器发送一个TankAlreadyExistMsg, 其他坦克检查自己的容器中是否有已经准备的坦克的信息, 如果有了就不添加, 没有则把它添加到容器中.

但是, 我们定义的TankNewMsg是发出一个坦克出生的信息, 如果把TankNewMsg同时用于引入旧坦克, 如果以后要修改TankNewMsg就会牵涉到其他的代码, 我们应该用一个新的消息来让新坦克把旧坦克加入到游戏中.

之前描述过存在的问题: 旧坦克能把新坦克加入到游戏中, 但是新坦克不能把旧坦克加入到游戏中, 当时使用的临时解决方案是: 旧坦克接收到TankNewMsg后判断该坦克是否已经存在自己的容器中, 如果不存在则添加进容器, 并且自己发送一个TankNewMsg, 这样新的坦克接收到旧坦克的TankNewMsg, 就能把旧坦克加入到游戏里.

当前如果有一辆坦克加入服务器后, 会向其他已存在的坦克发送TankNewMsg, 其他坦克接收到TankNewMsg会往自己的坦克容器中添加这辆新的坦克.

下面将介绍TankMoveMsg协议, 消息类型为2, 需要的数据有坦克id, 坦克坐标, 坦克方向, 炮筒方向. 每当自己坦克的方向发生改变时, 向服务器发送一个TankMoveMsg消息, 经服务器转发后, 其他客户端也能收该坦克的方向变化, 然后根据数据找到该坦克并设置方向等参数. 这样才能相互看到各自的坦克在移动.

一个较为简单的方法是旧坦克在接收到新坦克的信息后也发送一条TankNewMsg信息, 这样新坦克就能把旧坦克加入到游戏中. 下面是具体的代码. (显然这个方法不太好, 每个协议应该精细地一种操作, 留到以后进行改进)

但是这里涉及到一个问题: 已经连上服务器的客户端会收到新坦克的信息并把新坦克加入到自己的游戏中, 但是新坦克的游戏中并没有其他已经存在的坦克信息.

当我们的客户端和服务器完成TCP连接后, 客户端的UDP会向服务器的UDP发送一个TankNewMsg消息, 告诉服务器自己加入到了游戏中, 服务器会将这个消息转发到所有在服务器中注册过的客户端. 这样每个客户端都知道了有一个新的坦克加入, 它们会根据TankNewMsg中新坦克的信息创建出一个新的坦克对象, 并加入到自己的坦克容器中.

首先介绍的是TankNewMsg坦克出生协议, 消息类型为1. 它包含的字段有坦克id, 坦克坐标, 坦克方向, 坦克好坏.

在NetClient这个网络接口类中, 需要定义发送消息和接收消息的方法. 想一下, 如果我们为每个类型的消息编写发送和解析的方法, 那么程序将变得复杂冗长. 使用多态后, 每个消息实现类自己拥有发送和解析的方法, 要调用NetClient中的发送接口发送某个消息就方便多了. 下面代码可能解释的更清楚.

在描述整个应用层协议体系及具体应用前需要补充一下, 文章前面提到TankClient类用于控制整个游戏客户端, 但为了解耦, 客户端将需要进行的网络操作使用另外一个NetClient类进行封装.

此后, 整个坦克游戏的网络模型已经构建完毕, 游戏中的网络传输道路已经铺设好, 但想要在游戏中进行网络传输还差一样东西, 它就是这个网络游戏的应用层通信协议.

客户机连上服务器后, 两边分别获取了初始信息, 且客户端和服务器均开启了UDP线程. 客户端通过保存的服务器UDP端口号可以向服务器的UDP套接字发送UDP包, 服务器保存了所有连上它的Client客户端信息, 它可以向所有客户端的UDP端口发送UDP包.

同时服务器也会把自己的UDP端口号发送客户端, 因为服务器自身会开启一条UDP线程, 用于接收转发UDP包. 具体作用在后面会讲到.

生死狙击手游空投盒子这里补充一点, 为什么能获取客户端的IP地址? 因为服务器收到链路层帧后会提取出网络层数据报, 源地址的IP地址在IP数据报的首部字段中, Java对这一提取过程进行了封装, 所以我们能够直接在Java的api中获取源地址的IP.

服务器通过TCP和客户端连上后收到客户端的UDP端口号信息, 并将客户端的IP地址和UDP端口号封装成一个Client对象, 保存在容器中.

首先客户端通过TCP连接上服务器, 并把自己的UDP端口号发送给服务器, 这里省略描述TCP连接机制, 但是明白了连接机制后对为什么需要填写服务器端口号和IP会有更深的理解, 它们均为TCP报文段中必填的字段.

由于在TankClient类中的paint方法中需要画出图形, 根据面向对象的思想, 要画出一辆坦克, 应该由坦克调用自己的方法画出自己.

this.addWindowListener(new WindowAdapter() {//为窗口的关闭按钮添加监听

MissileDeadMsg mmsg = new MissileDeadMsg(m.getTankId(), m.getId());

g.drawString("explodes count:" + explodes.size(), 10, 70);

g.drawString("missiles count:" + missiles.size(), 10, 50);

在本项目中, 游戏的客户端由TankClient类控制, 游戏的运行和所有的图形操作都包含在这个类中, 下面会介绍一些主要的方法.

专题: 单机三国游戏7   三国类游戏单机   三国单机游戏r